Handling Errors -- perror( )

Chapter 20 - Concepts and Tools for Windows Applications

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

Programming Concepts and
Vocabulary for Windows
Windows programming is uniquely different for most programmers. The uniqueness occurs because Windows includes new programming concepts and its own special vocabulary. These new concepts and vocabulary can be broken down into two major categories: the features of Windows that are visible to the user, such as menus, dialog boxes, icons, and so on; and the invisible features such as messages, function access, and so on. There is a standard vocabulary associated with Windows programming development designed to give application developers the ability to communicate effectively with one another. Thus, all Windows features have been given a name and an associated usage. In this section, you will learn a variety of Windows terms that will give you the ability to confidently discuss and develop Windows applications.
What Is a Windows Window?
A Windows window appears to the user as a rectangular portion of the display device; its appearance is independent of the particular application at hand. To an application, however, the window is a rectangular area of the screen that is under the direct control of the application. The application has the ability to create and control everything about the main window, including its size and shape. When the user starts a program, a window is created. Each time the user clicks a window option, the application responds. Closing a window causes the application to terminate. Multiple windows convey to the user the multitasking capabilities of Windows. By partitioning the screen into different windows, the user can direct input to a specific application within the multitasking environment by using the keyboard or a mouse to select one of the concurrently running applications. Windows then intercepts the user’s input and allocates any necessary resources (such as the microprocessor) as needed.
The Layout of a Window
Features such as borders, control boxes, About boxes, and so on, are common to all Windows applications. It is this common interface that gives Windows a comforting predictability from one application to another. Figure 20-5 illustrates the fundamental components of a typical Windows window.
Figure 20-5: A basic Windows application
Border
A window has a border surrounding it. The border is made up of lines that frame the rectangular outline of the window. To the novice, the border may appear only to delineate one application’s screen viewport from another. Upon closer examination of the border, however, a different conclusion will be drawn. For example, by positioning the mouse pointer over a border and holding down the left mouse button, the user can change the size of the active window.
Title Bar
The name of the application program is displayed at the top of the window in the title bar. Title bars are located at the top of each associated window. Title bars can be very useful in helping to remember which applications are currently running. By default, the active application uses a different color in the title bar area than a non-active application.
Control Icon
A control icon is used by each Windows application. The control icon is a small image in each window’s upper-left corner. Clicking the mouse pointer on the control icon (referred to as clicking the control icon) causes Windows to display the system menu.
System Menu
The system menu is opened by clicking the mouse pointer on the control icon. The system menu provides standard application options such as Restore, Move, Size, Minimize, Maximize, and Close.
Minimize Icon
Each Windows application typically displays three iconic images in the upper-right corner of the window. The leftmost icon, a dash or underline symbol, allows the application to be minimized.
Maximize Icon
The maximize icon is in the middle of the three iconic images and appears as two very small windows. Use the maximize icon to make an application’s window fill the entire screen. If this icon is selected, all other application windows will be covered.
Close Window Icon
The close window icon is on the right of the three iconic images and appears as an “X” symbol. Use the close window icon to quickly exit an application. When this icon is selected for an application, the application ends and other applications move to the foreground.
Vertical Scroll Bar
An application can show a vertical scroll bar, if desired. The vertical scroll bar is located against the right-hand edge of the application’s window. The vertical scroll bar has opposite-pointing arrows at its extremes, a colored band, and a transparent window block. The transparent window block is used to visually represent the orientation between the currently displayed contents and the overall document (the colored band). Use the vertical scroll bar to select which of multiple pages of output are to be displayed. Clicking the mouse on either arrow typically shifts the display one line at a time. Clicking the mouse on the transparent window block, below the up arrow, and dragging it causes screen output to be quickly updated to any portion of the application’s screen output. One of the best uses of the vertical scroll bar is for quickly moving through a multipage word processing document. Word processors such as Microsoft Word and WordPerfect take advantage of vertical scroll bars.
Horizontal Scroll Bar
It is also possible to display a horizontal scroll bar. The horizontal scroll bar is displayed at the bottom of each window. The horizontal scroll bar is similar in function to the vertical scroll bar. You use the horizontal scroll bar to select which of multiple columns of information you would like displayed. Clicking the mouse on either arrow causes the screen image to typically be shifted one column at a time. Clicking the mouse on the transparent window block, to the right of the left-pointing arrow, and dragging it causes the screen output to be quickly updated to any horizontally shifted portion of the application’s screen output. One of the best uses for the horizontal scroll bar is for quickly moving through the multiple columns of a spreadsheet application, where the number of columns of information cannot fit into one screen width. Microsoft Excel makes good use of horizontal scroll bars.
Menu Bar
An optional menu bar can also be displayed just below the title bar in a window. Use the menu bar for making menu and submenu selections. Pointing and clicking the menu command or, alternately, using a hot-key combination makes menu selections. Hot-key combinations often use the alt key in conjunction with the underlined letter in a command, such as the “F” is in the command File.
Client Area
The client area usually occupies the largest portion of each window. The client area is the primary output area for the application. Managing the client area is the responsibility of the application program. Additionally, only the application can output to the client area.
A Procedure-oriented Windows Class
The basic components of a window help define the standard appearance of an application. There are also occasions when an application will create two windows with a similar appearance and behavior. Windows Paint is one such example. The fashion in which Paint allows the user to clip or copy a portion of a graphics image is achieved by running two instances (or copies) of Paint. Information is then copied from one instance to the other. Each instance of Paint looks and behaves like its counterpart. This requires each instance to create its own window with an identical appearance and functionality.
Windows that are created in this manner look alike and behave in a similar fashion. These windows are said to be of the same window class. However, windows that you create can take on different characteristics. They may be different sizes, placed in different areas of the display, have different text in the caption bars, have different display colors, use different mouse cursors, and so on.
Every created window must be based on a window class. With applications developed in C using traditional function calls, several window classes are registered by the Windows application during its initialization phase. Your application may register additional classes of its own. In order to allow several windows to be created and based on the same window class, Windows specifies some of a window’s characteristics as parameters to the CreateWindow( ) function, while others are specified in a window class structure. Also, when you register a window class, the class becomes available to all programs running under Windows. For object-oriented applications using Microsoft’s Foundation Classes, much of this registration work is already done through the use of predefined objects. In Chapter 21 you will learn how to write 32-bit Windows applications in C/C++ using traditional function calls. Chapters 22 and 23 are designed to teach you how to write similar 32-bit object-oriented applications with the Microsoft Foundation Class (MFC) library.
Windows of similar appearance and behavior can be grouped together into classes, thereby reducing the amount of information that needs to be maintained. Since each window class has its own shareable window class structure, there is no needless replication of the window class’ parameters. Also, two windows of the same class use the same function and any of its associated subroutines. This feature saves time and storage because there is no code duplication.
OOPs and Windows
Traditional C and C++ programs take on the characteristics of object-oriented programs under Windows. Recall that in object-oriented programming, an object is an abstract data type that consists of a data structure and various functions that act on the data structure. Likewise, objects receive messages that can cause them to function differently.
A Windows graphics object, for example, is a collection of data that can be manipulated as a whole entity and that is presented to the user as part of the visual interface. In particular, a graphics object implies both the data and the presentation of data. Menus, title bars, control boxes, and scroll bars are examples of graphics objects. The next sections describe several new graphics objects that affect the user’s view of an application.
Icons
An icon is a small graphics object used to remind the user of a particular operation, idea, or product. For example, a spreadsheet application when minimized could display a very small histogram icon to remind the user that the application is running. Double-clicking the mouse on the histogram would then cause Windows to bring the application to active status. Icons can be very powerful tools. They are good for gaining the user’s attention, as in the case of an error warning, and also when presenting choices to the user. Windows provides several stock icons, including a question mark, an exclamation point, an asterisk, an upturned palm icon, and so on. It is also possible to design your own device-independent color icons with the Microsoft C++ compiler’s resource editor.
Cursors
Cursors are also Windows graphics symbols that are used to follow the movement of the pointing device. The graphics symbol is capable of changing shapes to indicate particular Windows actions. For example, the standard Windows arrow cursor changes to the small hourglass cursor to indicate a pause while a selected command is being executed. Windows provides several stock cursors: a diagonal arrow, a vertical arrow, an hourglass, a cross hair, an I-beam, and several others. You can also use the Microsoft C++ compiler’s resource editor to create your own cursors.
Carets
Carets are symbols an application places in a window to show the user where input will be received. Carets are distinguished from other screen markers because they blink. Most of the time, mouse input is associated with a cursor and keyboard input with a caret. However, the mouse can move or change the input emphasis of a caret. To help clarify the difference between a cursor and a caret, Windows carets behave most similarly to the old DOS cursor. One of the carets provided for you automatically, when entering a dialog box, is the I-beam caret. Unlike in the cases of icons and cursors, an application must create its own carets using special functions. There are no stock carets.
Message Boxes
The message box is another common Windows graphics object. Message boxes are pop-up windows that contain a title, an icon, and a message. Figure 20-6 is the standard message box presented when terminating a Windows Notepad session:
Figure 20-6: A typical message box
The application needs to supply the message title, the message itself, and instructions on which stock icon to use (if any), and indicate if a stock response is allowed (such as OK). Additional stock user responses include Yes/No, Yes/No/Cancel, OK/Cancel, and Retry/Cancel. Stock icons include IconHand, IconQuestion, IconExclamation, IconAsterisk, and so on.
Windows Dialog Boxes
A dialog box is similar to a message box in that it too is a pop-up window. Dialog boxes, however, are primarily used to receive input from the user rather than to just present output. A dialog box allows an application to receive information one field at a time or one box’s worth of information at a time, rather than a character at a time. Figure 20-7 shows a typical Windows dialog box. Windows does the graphic design of a dialog box automatically for you. The layout of a dialog box is normally done with the compiler’s resource editor.
Figure 20-7: A typical dialog box for Windows
Fonts
A font is a graphics object or resource that defines a complete set of characters from one typeface. These characters are all of a certain size and style that can be manipulated to give text a variety of appearances. A typeface is a basic character design, defined by certain serifs and stroke widths. For instance, your application can use any of the different fonts provided with Windows, including System, Courier, and Times Roman, or custom fonts that you define and include in the application program’s executable file. By using built-in routines, Windows allows for the dynamic modification of a font, including boldface, italics, underline, and changing the size of the font. Windows provides all of the necessary functions for displaying text anywhere within the client area. Additionally, because of Windows device independence, an application’s output will have a consistent appearance from one output device to the next. TrueType font technology, first introduced with Windows 3.1, provides improved fonts for the screen and printer under all current versions of Windows.
Bitmaps
Bitmaps serve as a photographic image of the display (in pixels) and are stored in memory. Bitmaps are used whenever an application must display a graphics image quickly. Since bitmapped images are transferred directly from memory, they can be displayed more quickly than by executing the code necessary to re-create the image. There are two basic uses for bitmaps. First, bitmaps are used to draw pictures on the display. For example, Windows uses many small bitmaps for drawing arrows in scroll bars; displaying the check marks when selecting pop-up menu options; and drawing the system menu box, the size box, and many others. Bitmaps are also used for creating brushes. Brushes allow you to paint and fill objects on the screen.
There are two disadvantages to using bitmaps. First, depending on their size, bitmaps can occupy an unpredictably large portion of memory. For each pixel that is displayed, there needs to be an equivalent representation in memory. Displaying the same bitmap on a color monitor versus a monochrome monitor would also require more memory. On a monochrome monitor, 1 bit can be used to define a pixel’s being on or off. However, on a color monitor that can display 16 colors, each pixel would require 4 bits, or a nibble, to represent its characteristics. Also, as the resolution of the display device increases, so too does the memory requirement for the bitmap. Another disadvantage of bitmaps is that they contain only a static picture. For example, if an automobile is represented by a bitmap, there is no way to access the picture’s various components, such as tires, hood, window, and so on. However, if the automobile had been constructed from a series of primitive drawing routines, an application would be able to change the data sent to these routines and modify individual items in the picture. For example, an application could modify the roofline and convert a sedan to a convertible. You can create or modify bitmaps with the compiler’s resource editor.
Pens
Windows uses information on the current pen when it draws a shape on the screen. Pens are used to draw lines and outline shapes. Pens have three basic characteristics: line width, style (dotted, dashed, solid), and color. Windows always has a pen for drawing black lines and one for drawing white lines available to each application. It is also possible to create your own unique pens. For example, you might want to create a thick light-gray line to outline a portion of the screen or a dot-dash-dot line for spreadsheet data analysis.
Brushes
Windows uses brushes to paint colors and fill areas with predefined patterns. Brushes have a minimum size of 8 8 pixels and, like pens, have three basic characteristics: size, pattern, and color. With their 8 8-pixel minimum size, brushes are said to have a pattern, not a style as pens do. The pattern may be a solid color, hatched, diagonal, or any other user-definable combination.
Windows Messages
As you have learned, an application does not write directly to the screen under Windows. Neither does an application directly process hardware interrupts or output directly to the printer. Instead, an application uses the appropriate Windows functions or waits for an appropriate message to be delivered. Applications development under Windows must now incorporate the processing of the application and the user’s view of the application through Windows.
The Windows message system is the underlying structure used to disseminate information in a multitasking environment. From the application’s viewpoint, a message is seen as a notification that some event of interest has occurred that may or may not need a specific response. These events may have been initiated on the part of the user, such as clicking or moving the mouse, changing the size of a window, or making a menu selection. However, the signaled event could also have been generated by the application itself.
The overall effect of this process is that your application must now be totally oriented toward the processing of messages. It must be capable of awakening, determining the appropriate action based on the type of message received, taking that action to completion, and returning to sleep.
Windows applications are significantly different from their older DOS counterparts. Windows provides an application program with access to hundreds of function calls, directly or indirectly, through foundation classes. These function calls are handled by several main modules, including the KERNEL, GDI (graphics device interface), and USER modules. The KERNEL is responsible for memory management, loading and running an application, and scheduling. The GDI contains all of the routines to create and display graphics. The USER module takes care of all other application requirements.
The next section takes a closer look at the message system by examining the format and sources of messages and looking at several common message types and the ways in which both Windows and your application process messages.
The Windows Message Format
Messages are used to notify a program that an event of interest has occurred. Technically, a message is not just of interest to the application, but also to a specific window within that application. Therefore, every message is addressed to a window.
Actually, only one message system exists under Windows—the system message queue. However, each program currently running under Windows also has its own program message queue. The USER module must eventually transfer each message in the system message queue to a program’s message queue. The program’s message queue stores all messages for all windows in that program.
Four parameters are associated with all messages, regardless of their type: a window handle, a message type, and two additional 32-bit parameters. The first parameter specified in a window message is the handle of the window to which the message is addressed.
  Note These are the parameters for 32-bit Windows applications. The parameters used for earlier 16-bit Windows 3.x applications differed.
Table 20-1 shows a list of data types frequently used with Win32 functions.
Table 20-1: Frequently Used Win32 Data Types
Type
Description
CALLBACK
Replaces FAR PASCAL in application’s call back routine.
HANDLE
A 32-bit unsigned integer that is used as a handle.
HDC
A handle to a device context.
HWND
A 32-bit unsigned integer that is used as the handle to a window.
LONG
A 32-bit signed integer
LPARAM
Type used for declaration of lParam.
LPCSTR
LPCSTR is the same as LPSTR, but is used for read-only
string pointers.
LPSTR
A 32-bit pointer.
LPVOID
A generic pointer type. It is equivalent to (void *).
LRESULT
Used for the return value of a window procedure.
NULL
An integral zero value. It is frequently used to trigger default parameters or actions for a function.
UINT
An unsigned integer type. The host environment determines the size of UINT. For Windows 95 and NT, it is 32-bits.
WCHAR
A 16-bit UNICODE character. WCHAR is used to represent all of the symbols for all of the world’s languages.
WINAPI
Replaces FAR PASCAL in API declarations.
WPARAM
Used for the declaration of wParam.
Handles are always used when writing procedure-oriented Windows applications. Remember that a handle is a unique number that identifies many different types of objects, such as windows, controls, menus, icons, pens and brushes, memory allocation, output devices, and even window instances. Under Windows, each loaded copy of a program is called an instance.
Because Windows allows you to run more than one copy of the same application at the same time, the operating system needs to keep track of each of these instances. It does this by attaching a unique instance handle to each running copy of the application.
The instance handle is usually used as an index into an internally maintained table. By referencing a table element rather than an actual memory address, Windows can dynamically rearrange all resources simply by inserting a new address into the resource’s table position. For example, if Windows associates a particular application’s resource with table lookup position 16, then no matter where Windows moves the resource in memory, table position 16 will contain the resource’s current location.
Windows conserves memory resources because of the way multiple instances of the same application are handled. Several multitasking environments load each duplicate instance of an application just as if each was an entirely new application.
The instance of an application has a very important role. It is the instance of an application that defines all of the objects necessary for the functioning of the application. This can include controls, menus, dialog boxes, and much more, along with new window classes.
The second parameter in a message is the message type. This is one of the identifiers specified in several header files unique to Windows. These header files can be pointed to with the use of WINDOWS.H. With Windows, each message type begins with a two-character mnemonic, followed by the underscore character and, finally, a descriptor. The most frequently encountered type of message in traditional C and C++ Windows applications is the window message. Windows messages include WM_CREATE, WM_PAINT, WM_CLOSE, WM_COPY, WM_PASTE, etc. Other message types include control window messages (BM_), edit control messages (EM_), and list box messages (LB_). An application can also create and register its own message type. This permits the use of private message types.
The last two parameters provide additional information necessary to interpret the message. The contents of these last two parameters will therefore vary depending on the message type. Examples of the types of information that would be passed include which key was just struck, the position of the mouse, the position of the vertical or horizontal scroll bar elevators, and the selected pop-up menu item.
Generating Messages
It is the message-passing concept that allows Windows to be multitasking. Thus, Windows must process all messages. There are four basic sources for a message. An application can receive a message from the user, from Windows itself, from the application program itself, or from other applications.
User messages include keystroke information, mouse movements, point-and-click coordinates, any menu selections, the location of scroll bar elevators, and so on. The application program will devote a great deal of time to processing user messages. User-originated messages indicate that the person running the program wants to change the way the application is viewed.
A message is sent to an application whenever a state change is to take effect. An example of this would be when the user clicks an application’s icon indicating that they want to make that application the active application. In this case, Windows tells the application that its main window is being opened, that its size and location are being modified, and so on. Depending on the current state of an application, Windows-originated messages can be processed or ignored.
In Chapter 21, you will learn how to write simple Windows applications in C and C++. When you do this, you will see that the program is broken down into specific procedures, with each procedure processing a particular message type for a particular window. One procedure, for example, will deal with resizing the application’s window. It is quite possible that the application may want to resize itself. In other words, the source of the message is the application itself.
Currently, most applications written for Windows do not take full advantage of the fourth type of message source, intertask communication. However, this category will become increasingly important as more and more applications take advantage of this Windows integration capability. Microsoft’s Dynamic Data Exchange protocol (DDE) was the first to take advantage of this feature.
Responding to Messages
Traditional C and C++ procedure-oriented Windows applications have a procedure for processing each type of message they may encounter. Different windows can respond differently to messages of the same type. For example, one application may have created two windows that respond to a mouse-button click in two different ways. The first window could respond to a mouse-button click by changing the background color, while the second window may respond to the mouse-button click by placing a crosshatch on a spreadsheet. It is because the same message can be interpreted differently by different windows that Windows addresses each message to a specific window within an application. Not only will the application have a different procedure to handle each message type, it will also need a procedure to handle each message type for each window. The window procedure groups together all the message-type procedures for an application.
The Message Loop
A basic component of all Windows applications is the message-processing loop. The location of the message loop in procedure-oriented applications is easy to identify. In object-oriented code, the message loop is processed in the CWinAPP foundation class.
Each C and C++ application performs the operation internally. These applications contain procedures to create and initialize windows, followed by the message- processing loop and, finally, some code required to close the application. The message loop is responsible for processing a message delivered by Windows to the main body of the program. Here, the program acknowledges the message and then requests Windows to send it to the appropriate window procedure for processing. When the message is received, the window procedure executes the desired action.
Two factors that can influence the sequence in which a message is processed are the message queue and the dispatching priority. Messages can be sent from one of two queues—either the system queue or the application’s message queue. Messages, regardless of the source, are first placed in the system queue. When a given message reaches the front of the queue, it is sent to the appropriate application’s message queue. This dual-mode action allows Windows to keep track of all messages and permits each application to concern itself with only those messages that pertain to it.
Messages are placed in the queues as you would expect: FIFO (first in, first out) order. These are called synchronous messages. Most Windows applications use this type of dispatching method. However, there are occasions when Windows will push a message to the end of the queue, thereby preventing it from being dispatched. Messages of this type are called asynchronous messages. Care must be taken when sending an asynchronous message that overrides the application’s normal sequence of processing.
Several types of asynchronous messages exist, including paint, timer, and quit messages. A timer message, for example, causes a certain action to take effect at a specified time, regardless of the messages to be processed at that moment. A timer message has priority, and will cause all other messages in the queue to be pushed farther from the queue front.
A few asynchronous messages can be sent to other applications. This is unique because the receiving application doesn’t put the message into its queue. Rather, the received message directly calls the application’s appropriate window procedure, where it is immediately executed.
How does Windows dispatch messages that are pending for several applications at the same time? Windows handles this problem in one of two ways. One method of message processing is called dispatching priority. Whenever Windows loads an application, it sets the application’s priority to zero. Once the application is running, however, the application can change its priority. With everything else being equal, Windows will settle any message-dispatching contention by sending messages to the highest priority application.
One example of a high-priority program would be a data communications application. Tampering with an application’s priority level is not recommended, and is very uncommon. Windows has another method for dispatching messages to concurrent applications of the same priority level. Whenever Windows sees that a particular application has a backlog of unprocessed messages, it hangs onto the new message while continuing to dispatch other new messages to the other applications.
Accessing Windows Functions
As you have learned, Windows provides the application developer with hundreds of functions. Examples of these functions include DispatchMessage( ), PostMessage( ), RegisterWindowMessage( ), and SetActiveWindow( ). For C++ programmers using the Microsoft Foundation Classes (MFC), many of these functions are dispatched automatically.
Calling Convention for Functions
Function declarations under 16-bit Windows 3.x included the pascal modifier, which was more efficient under DOS. Windows does not use this modifier for 32-bit applications. As you have learned, the parameters to all Windows functions are passed via the system stack. The parameters for the function are pushed from the rightmost parameter to the leftmost parameter, in a normal C and C++ fashion. Upon return from the function, the calling procedure must adjust the stack pointer to a value equal to the number of bytes originally pushed onto the stack.
The Windows Header File: WINDOWS.H
The WINDOWS.H header file provides a path to over a thousand constant declarations, typedef declarations, and hundreds of function prototypes. One of the main reasons a Windows application takes longer to compile than a non-Windows C or C++ program is the size of this and associated header files. The WINDOWS.H header file (and associated header files) is an integral part of all programs. Traditionally, WINDOWS.H is a required include file in all C and C++ Windows applications. When using the Microsoft Foundation Class library in C++, the WINDOWS.H header file is included via the AFXWIN.H header file.
Usually, the #define statements found in WINDOWS.H or its associated files map a numeric constant with a text identifier. For example:
#define WM_CREATE 0x0001
In this case, the Visual C++ compiler will use the hexadecimal constant 0x0001 as a replacement for WM_CREATE during preprocessing.
Other #define statements may appear a bit unusual. For example:
#define NEAR near
#define VOID void
In Visual C++, both near and void are reserved words. Your applications should use the uppercase NEAR and VOID for one very good reason: if you port your application to another compiler, it will be much easier to change the #define statements within the header file than to change all of the occurrences of a particular identifier in your application.
Components that Make Up a Windows Application
There are several important steps that are common in developing all Windows applications:
  Create the WinMain( ) and associated Windows functions in C or C++. You can also utilize foundation classes, such as CWinAPP, in C++.
  Create the menu, dialog box, and any additional resource descriptions and put them into a resource script file.
  (Optional) Use the appropriate resource editor in the Visual C++ compiler to create unique cursors, icons, and bitmaps.
  (Optional) Use the appropriate resource editor in the Visual C++ compiler to create dialog boxes.
  Compile and link all C/C++ language sources and resource files using a
project file.
The actual creation of a Windows application requires the use of several new development tools. Before developing applications in C or C++, an understanding of these tools is needed. The next section briefly discusses the tools supplied with the Visual C++ compiler as they relate to creating a Windows application.

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net