Monday 28 November 2011

What is window subclassing? in C programming

What is window sub classing?

Windows subclassing refers to a technique whereby you can “tap” into a built-in Windows function and add your own functionality without disturbing or abandoning the original Windows functionality. For example, the Windows procedure for a check box control is coded deep within the system internals of Windows, and the source code is not readily available. However, through the use of two Windows API functions, you can tap into this code and build your own functionality into it.

The two Windows API functions that accomplish this task are called GetWindowLong() and SetWindowLong(). The GetWindowLong() function returns the address of the Windows procedure you want to subclass. The SetWindowLong() function can be used to override the default Windows procedure and point to your own custom-made version. Note that you do not have to replicate all functionality by doing this—when you need to reference the original procedure’s functionality, you can pass the messages through to it.

You can save the old procedure’s address by including the following code in your program: 

lpfnOldCheckBoxProc = (FARPROC) GetWindowLong(hwndCheckBox, GWL_WNDPROC); 

Your new custom check box procedure can replace the old procedure by including the following code in your program:

SetWindowLong(hwndCheckBox, GWL_WNDPROC, (LONG) lpfnCustomCheckBoxProc);

In this example, the GetWindowLong() function is used to save the old procedure’s address. The GWL_WNDPROC identifier tells the GetWindowLong() function to return a pointer to the check box’s procedure. After this is saved, a new procedure (named lpfnCustomCheckBoxProc) is invoked by a call to the SetWindowLong() function. Now, whenever Windows would normally call hwndCheckBox’s default procedure, your custom check box procedure will be called instead.

In your custom check box procedure, you can always pass messages through to the original procedure. This
is done by using the Windows API function CallWindowProc() as shown here:

CallWindowProc(lpfnOldCheckBoxProc, hwnd, message, wParam, lParam);

This way, you do not have to replicate all functionality that was in the original procedure. Instead, you can trap for only the messages you want to customize. For instance, if you have ever seen a variation of a check box (such as Borland’s custom check box), you know that it does not look like the default check box you would normally see in Windows programs. This variation is accomplished through Windows subclassing.The WM_PAINT message is simply subclassed out, and a new customized version of the check box rather than the original version is painted.

Cross Reference:
XXI.27: What is a static child window?

What is a static child window in C programming

What is a static child window

A static child window is a window control that does not accept mouse or keyboard input. Typical examples of static child windows are rectangles, frames, a window’s background or border, and static text (labels) that appear on-screen. Typically, it makes no sense to process mouse or keyboard events when dealing with static controls.

A static control can be created by specifying the “static” class in the Windows API CreateWindow() function
call. Here is an example of a field label that is created by invoking the CreateWindow() function: 

hwndNameLabel = CreateWindow (“static”, “Customer Name:”,
WS_CHILD | WS_VISIBLE | SS_LEFT,
0, 0, 0, 0,
hwnd,
50,
hInstance, NULL) ;

This example creates a field label in the window with the caption “Customer Name:.” This field label would probably coincide with a window of the edit class that would accept the user’s input of the customer’s name.
 
Cross Reference:
XXI.28: What is window subclassing?

How do you create your own buttons or controls? in C programming

How do you create your own buttons or controls?

Controls such as buttons are typically created with a resource editor. With a resource editor, you can interactively design your windows and place pushbuttons, check boxes, radio buttons, and other controls in your window. You can then access them from within your Windows program by referring to each resource’s unique resource id (which you define).

This is not the only way, however, to create controls such as buttons. Buttons and other controls are called “child window controls.” Each child window control has the capability to trap incoming messages (such as the WM_COMMAND message) and pass them on to the parent window control. A child window control such as a pushbutton can be created by using the Windows API function CreateWindow(). It might seem odd to call the function CreateWindow() to create a pushbutton, but a control is, in effect, its own “virtual” window, and thus it needs to have its own handle. Here is some sample code that shows how this task is performed: ...
 
switch (message)
{
...
case WM_CREATE:
hwndCloseButton =
CreateWindow(“button”, /* Windows registered class name */
“Close”, /* Window text (title) */
WS_CHILD | WS_VISIBLE | PUSHBUTTON, /* Style */
50, /* Horizontal position */
50, /* Vertical position */
100, /* Width */
100, /* Height */
hwndParent, /* Handle of parent window */
0, /* Child-window identifier */
((LPCREATESTRUCT) lParam)->hInstance,
NULL); /* Window creation options */
...
}

What are the system color constants? in C programming

What are the system color constants?

he system color constants are used by Windows to control the colors of various objects included in the Windows environment. Table XXI.25 lists the system color constants (as defined in windows.h).

The system color constants.
----------------------------------------------------------------------------------------------------------
Color Constant                                   Target Object
---------------------------------------------------------------------------------------------------------
COLOR_SCROLLBAR                     Scrollbar
COLOR_BACKGROUND               Windows desktop
COLOR_ACTIVECAPTION            Active title
COLOR_INACTIVECAPTION        Inactive title
COLOR_MENU                                Menu bar
COLOR_WINDOW                          Window
COLOR_WINDOWFRAME             Window frame
COLOR_MENUTEXT                       Menu text
COLOR_WINDOWTEXT                 Window text
COLOR_CAPTIONTEXT                  Title text
COLOR_ACTIVEBORDER               Active border
COLOR_INACTIVEBORDER           Inactive border
COLOR_APPWORKSPACE             Application workspace
COLOR_HIGHLIGHT                        Highlight
COLOR_HIGHLIGHTTEXT              Highlight text
COLOR_BTNFACE                           Button face
COLOR_BTNSHADOW                    Button shadow
COLOR_GRAYTEXT                        Grayed-out text
COLOR_BTNTEXT                           Button text
------------------------------------------------------------------------------------------------------------

You can change the system colors from within your Windows programs by calling the GetSysColor() and SetSysColor() functions. You can also set these colors by altering the [colors] section of your WIN.INI (Windows initialization) file, or you can interactively set them by using the Windows control panel.

Cross Reference:

XXI.24: How do you access the system colors in a Windows program?

How do you access the system colors in a Windows program? in C programming

How do you access the system colors in a Windows program?

You can obtain the system colors by calling the Windows API function GetSysColor(). The GetSysColor() function takes one parameter, which signifies which color element you want to obtain. The color elements are represented by color constants defined in the windows.h header file. The Windows system color constants are listed in the following FAQ (XXI.25). 

For instance, to obtain the color for the window’s active border, you might make the following function call:

rgbColor = GetSysColor(COLOR_ACTIVEBORDER

The GetSysColor() function returns an RGB value. The RGB value represents the intensity of the colors red, green, and blue that are present in the returned color. An RGB value of 0 signifies black, and an RGB value of 255 signifies white. You can extract the individual red, green, and blue values from the RGB value by calling the GetRValue(), GetGValue(), and GetBValue() Windows API functions.

The Windows API function SetSysColors() can be used to set system colors. Here is an example of some
code that sets the color of the active border to red:

int aiColorElements[1];
DWORD argbColor[1];
aiColorElements[0] = COLOR_ACTIVEBORDER;
argbColor[0] = RGB(0xFF, 0x00, 0x00);
SetSysColors(1, aiColorElements, argbColor);

The SetSysColors() function takes three arguments. The first argument is the number of elements to set color for, the second is an array of integers holding the system color constants to set color for, and the third is an array of RGB values that correspond to the colors you want to invoke for the elements represented by the second argument.

Cross Reference:

XXI.25: What are the system color constants?

How do you update the title bar in a Windows program? in C programming

How do you update the title bar in a Windows program?

The title bar (or caption bar, as it is often called) can be updated in a Windows program by using the Windows API function SetWindowText(). The SetWindowText() function takes two parameters. The first parameter is the handle to the window, and the second parameter is the new title you want to display on the window.

One reason you might want to take this action is to provide your users with the current date and time on the title bar. This task can be accomplished with the following code:

char* szAmPm = “PM”;
char szNewCaption[200];
struct tm* tmToday;
time_t lTime;
time(&lTime);
tmToday = localtime(lTime);
wsprintf(szNewCaption,
“My Application - %02d/%02d/%02d %02d:%02d:%02d %s”,
tmToday->tm_month, tmToday->tm_mday, tmToday->tm_year,
tmToday->tm_hour, tmToday->tm_min,
tmToday->tm_sec, szAmPm);
SetWindowText(hwnd, szNewCaption);
Of course, you probably will want to set up this code in some sort of timer event loop so that the title is
updated every second (or minute).

Cross Reference:

None

How do you get the date and time in a Windows program? in C programming

How do you get the date and time in a Windows program?

To get the date and time in a Windows program, you should call the standard C library functions time() and localtime() or some derivative (asctime(), ctime(), _ftime(), gmttime()). These functions are compatible with both DOS and Windows. You should never attempt to call a DOS-only or a ROM BIOSfunction directly. You should always use either Windows API function calls or standard C library routines. Here is an example of code that can be used to print the current date and time in a Windows program:

char* szAmPm = “PM”;
char szCurrTime[128];
char szCurrDate[128];
struct tm* tmToday;
time_t lTime;
time(&lTime);
tmToday = localtime(lTime);
wsprintf(szCurrDate, “Current Date: %02d/%02d/%02d”,
tmToday->tm_month, tmToday->tm_mday,
tmToday->tm_year);
if (tmToday->tm_hour < 12 )
strcpy(szAmPm, “AM” );
if (tmToday->tm_hour > 12 )
tmToday->tm_hour -= 12;
wsprintf(szCurrTime, “Current Time: %02d:%02d:%02d %s”,
tmToday->tm_hour, tmToday->tm_min,
tmToday->tm_sec, szAmPm);
TextOut(50, 50, szCurrDate, strlen(szCurrDate));
TextOut(200, 50, szCurrTime, strlen(szCurrTime));
}

The time() and localtime() functions are used to get the current local time (according to the Windows timer, which gets its time from MS-DOS). The time() function returns a time_t variable, and the localtime() function returns a tm structure. The tm structure can easily be used to put the current date and time into a readable format. After this task is completed, the wsprintf() function is used to format the date and time into two strings, szCurrDate and szCurrTime, which are then printed in the current window via  the TextOut() Windows API function call.

Cross Reference:

None.

How do you create an animated bitmap? in C programming

How do you create an animated bitmap?

Sometimes you will run across a Windows program that entertains you with an animated bitmap. How is this task accomplished? One method is to set up a timer event that switches the bitmap every second or two, thus making the bitmap “appear” to be animated. In fact, it is not animated, but rather several versions of the same bitmap are switched fast enough to make it appear as though the bitmap is moving.

The first step is to insert the following code into your WinMain() function:
SetTimer(hwnd, 1, 1000, NULL);

This code sets up a timer event that will be invoked every 1000 clock ticks (1 second). In your event (message)
loop, you can then trap the timer event, as shown here:
switch(message)
{
case WM_TIMER:
/* trapped timer event; perform something here */
}

Now, when the WM_CREATE message comes through, you can load the original bitmap:
case WM_CREATE:
hBitmap = LoadBitmap(hInstance, BMP_ButterflyWingsDown);
In this case, BMP_ButterflyWingsDown is a bitmap resource bound to the executable through the use of a
resource editor. Every time a WM_TIMER event is triggered, the following code is performed:
case WM_TIMER:
if (bWingsUp)
hBitmap = LoadBitmap(hInstance, BMP_ButterflyWingsDown);
else
hBitmap = LoadBitmap(hInstance, BMP_ButterflyWingsUp);

This way, by using the boolean flag bWingsUp, you can determine whether the butterfly bitmap’s wings are up or down. If they are up, you display the bitmap with the wings down. If they are down, you display the bitmap with the wings up. This technique gives the illusion that the butterfly is flying.

Cross Reference:

None.

Can a mouse click be captured in an area outside your program’s client area? in C programming

Can a mouse click be captured in an area outside your program’s client area?

In Windows, the client area of your program includes all the space within the border of your window, with the exception of the following areas:
  •   The title bar
  •  The scrollbars
  •   The pull-down menu
Can a mouse click be captured within any of these three regions? Yes. When the mouse is clicked in these regions, Windows sends a “nonclient area” message to your program. This way, you can trap for these events
when they occur.

Trapping for these events is unusual, however. This is because Windows has prebuilt functionality to handle mouse clicks in these regions. For instance, if you double-click on a window’s title bar, the window resizes itself (maximized or restored). If you click on a scrollbar, the window scrolls. If you click on a pull-down menu, the menu is shown on-screen. None of these events requires any code to be written—they are automatically handled by Windows.

Most of the time, you will want to pass these messages to what is called the DefWindowProc() function. The DefWindowProc() calls the default window procedure (that is, it implements the window’s built-in functionality). You very rarely would need to trap for a nonclient mouse hit. Nonetheless, Table XXI.20 presents some of the messages you can trap for.

Nonclient area mouse events.
--------------------------------------------------------------------------------------------------------------
Nonclient Message                                   Meaning
--------------------------------------------------------------------------------------------------------------
WM_NCLBUTTONDOWN                   Nonclient left mouse button down
WM_NCMBUTTONDOWN                  Nonclient middle mouse button down
WM_NCRBUTTONDOWN                   Nonclient right mouse button down
WM_NCLBUTTONUP                           Nonclient left mouse button up
WM_NCMBUTTONUP                          Nonclient middle mouse button up
WM_NCRBUTTONUP                           Nonclient right mouse button up
WM_NCLBUTTONDBLCLK                 Nonclient left mouse button double-click
WM_NCMBUTTONDBLCLK                Nonclient middle mouse button double-click
WM_NCRBUTTONDBLCLK                 Nonclient right mouse button double-click
--------------------------------------------------------------------------------------------------------------

Cross Reference:

XXI.14: How do you determine a Windows program’s client area size?

What is the difference between the caret and the cursor? in C programming

What is the difference between the caret and the cursor?

In Windows, the cursor represents the mouse position on the screen. The caret represents the current editing position. If you look at the Windows program Notepad, for example, you’ll notice that as you move the mouse around, you see the familiar arrow move. This arrow is the cursor; it represents the current position
of the mouse.

If you type some text into the Notepad program, you’ll notice that the next available edit position in the Notepad window has a blinking vertical bar in it. This is the caret; it represents the current editing position. You can control the caret’s blink rate by invoking the Windows control panel. In Windows programs, five functions are available to control the caret. These functions are listed in Table

Functions to control the caret.
-----------------------------------------------------------------------------------------------------------------
Function Name                               Purpose
----------------------------------------------------------------------------------------------------------------
CreateCaret                                   Creates a caret
SetCaretPos                                   Sets the position of the caret
ShowCaret                                     Shows the caret
HideCaret                                       Hides the caret
DestroyCaret                                  Destroys the caret
------------------------------------------------------------------------------------------------------------------

If you’re a die-hard DOS programmer moving into Windows programming, you might think it odd that the “cursor” position actually represents the mouse position and not the editing position. This is just one little caveat you must get used to when joining the ranks of Windows programmers who now have to refer to the “cursor” position as the “caret” position.

Cross Reference:

None.

What is a dead key? in C programming

What is a dead key?

A dead key is a keystroke that is not recognizable by Windows. On some international keyboards, it is impossible to translate certain characters into keystrokes. In this case, Windows sends either a WM_DEADCHAR or a WM_SYSDEADCHAR message to your program, indicating that Windows cannot interpret the character code of the incoming keystroke

You can, however, manually reference the actual ASCII character code of the incoming character. When your program receives one of these two messages, you can inspect the value of the wParam parameter and determine which key was pressed. You therefore can manually customize your programs for internationalization by determining ahead of time which foreign characters your program needs to handle.

Cross Reference:

XXI.15: What are OEM key codes?
XXI.16: Should a Windows program care about the OEM key codes?
XXI.17: What are virtual key codes?

What are virtual key codes? in C programming

What are virtual key codes?

When your program receives a WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message, the wParam parameter will contain the keystroke’s virtual key code. This virtual key code can be used to reference what key on the keyboard was pressed. The key code does not map to any physical character set (such as the OEM key codes—see FAQ XXI.16), but rather it originates from a “virtual” table (set forth in windows.h) of key codes. Table XXI.17 lists some available virtual key codes.



















Many more virtual keys are available, but most of them depend on which international settings you have set up for your Windows configuration.

Note that besides being able to obtain the keystroke from Windows, you can also obtain the state of the Shift, Ctrl (Control), and Alt keys. You can do so by using the function GetKeyState(). For instance, the function
call
GetKeyState(VK_SHIFT);

returns a negative value if the Shift key is down (pressed). If the Shift key is not pressed, the return value is
positive.

Cross Reference:

XXI.15: What are OEM key codes?
XXI.16: Should a Windows program care about the OEM key codes?
XXI.18: What is a dead key?

Should a Windows program care about the OEM key codes?in C programming

Should a Windows program care about the OEM key codes?

No. As FAQ XXI.15 explains, OEM key codes refer to the original 255 characters of the IBM character set
that comes preprogrammed into every 80x86 ROM.

Many of these characters were used in older DOS-based programs to represent characters that normally would have required graphics. Because Windows is a graphical environment that contains hundreds of functions for creating graphical objects, these characters are no longer needed. Instead of writing Windows functions to use the OEM character set to draw a rectangle, for instance, you can simply call the Windows API function Rectangle(). Thus, the OEM character codes are not needed in Windows, and you can effectively ignore them when writing your Windows programs.

Note that although you can ignore these key codes, Windows cannot. For instance, you probably already know that many of your DOS programs can be run in a window under Windows. When this is the case, Windows must “interpret” the DOS program’s use of the OEM character set and map it accordingly on-screen.

Cross Reference:

XXI.15: What are OEM key codes?
XXI.17: What are virtual key codes?
XXI.18: What is a dead key?

What are OEM key codes? in C programming

What are OEM key codes?

The OEM (Original Equipment Manufacturer) key codes refer to the original 255 characters preprogrammed into all IBM-compatible ROMs—everything from hex 00 to hex FF. These characters not only represent the uppercase and lowercase characters of the alphabet, but also contain several nonprintable characters (tab, bell, carriage return, linefeed, and such) and several “graphical” characters used for line drawing. This character set also contains some symbols for representing fractions, pi, infinity, and others. Many DOSbased programs use this character set to print graphics on-screen, because these 255 characters are the only ones available for DOS to use.

Cross Reference:

XXI.16: Should a Windows program care about the OEM key codes?
XXI.17: What are virtual key codes?
XXI.18: What is a dead key?

in C programming

How do you determine a Windows program’s client area size?

Your program’s client area size is defined as the height and width of your program’s window that is displayed
on-screen. The client area size can be determined by processing the WM_SIZE message in your program’s event loop. The WM_SIZE message contains three parameters, two of which can be used to determine your client area size. Your program’s event loop (window procedure) is passed a parameter named lParam that can be evaluated when a WM_SIZE message is received. The low-order word of the lParam variable contains your program’s client area width, and the high-order word of the lParam variable contains your program’s client area height. Here is an example of determining client area size:

switch (message)
{
...
case WM_SIZE:
nProgramWidth = LOWORD(lParam);
nProgramHeight = HIWORD(lParam);
...
}

LOWORD and HIWORD are actually macros defined in windows.h that extract the low-order and high-order words, respectively.

Cross Reference:

XXI.20: Can a mouse click be captured in an area outside your program’s client area?

Will Windows always save and refresh your program’s windows? in C programming

Will Windows always save and refresh your program’s windows?

No. Windows itself is not responsible for saving and restoring your program’s windows. Instead, Windows sends a message to your program—the WM_PAINT message—that notifies your program that its client area needs repainting.

The client area refers to the portion of the screen that your program is in control of—that is, the portion of the screen occupied by your program’s windows. Whenever another program overlays your program with another window, your client area is covered by that application’s window. When that application’s window is removed, Windows sends a WM_PAINT message to your program. Your Windows program should contain an event loop that looks for and responds to such messages. When your program receives the WM_PAINT message, you are responsible for initiating the appropriate code to repaint your application’s window.

The WM_PAINT message is generated by Windows when one of the following events occurs:
  •  A previously hidden portion of your program’s client area is uncovered.
  •   Your application’s window is moved or resized.
  •   Your application’s window is scrolled by the use of a scrollbar.
  •  A pull-down or pop-up menu is invoked.
Additionally, you can force your program to repaint the screen (thus generating a WM_PAINT message to your own program) by calling the Windows API function InvalidateRect(). 

Your program should contain an event loop that captures incoming messages and responds to them. Here is an example of a typical event loop that responds to a WM_PAINT message:

switch(message)
{
...
case WM_PAINT:
hdcOutput = BeginPaint(hwndMyWindow, &psPaint);
hpenDraw = CreatePen(PS_SOLID, 3, 0L);
SelectObject(hdcOutput, hpenDraw);
Rectangle(hdcOutput, 0, 0, 150, 150);
TextOut(hdcOutput, 200, 200, “Just the FAQ’s, Ma’am...”, 24);
...
}

When the preceding program is run, a WM_PAINT message is generated by Windows on program start-up and any time the client area is moved, resized, or scrolled. It should be noted that actions such as cursor movement and drag-and-drop operations do not require a WM_PAINT message to be generated. In these cases, Windows saves and restores the portion of the screen that has been covered with the cursor or icon.

Cross Reference:

XXI.14: How do you determine a Windows program’s client area size?

Are Windows programs compatible from one compiler to the next? in C programming

Are Windows programs compatible from one compiler to the next?

All compilers available for development of Microsoft Windows programs must support the Microsoft Windows SDK (Software Development Kit), and therefore the Windows functions you use in your programs are compatible across compilers. A typical Windows program developed in standard C using only Windows API calls should compile cleanly for all Windows-compatible compilers. The functions provided in the Windows API are compiler-independent and easy to port between compilers such as Borland C++, Microsoft Visual C++, and Symantec C++.

Most of the Windows-based programs on the market today, however, use C++ class libraries to augment and simplify the complexity of using the Windows SDK. Some class libraries, such as Microsoft’s Foundation Class Library (MFC) and Borland’s ObjectWindows Library (OWL), are compiler-specific. This means that you cannot take a Windows program developed with MFC using Microsoft’s Visual C++ and port it to Borland C++, nor can you take a Windows program developed with OWL using Borland C++ and port it to Visual C++. Some class libraries, such as zApp and Zinc, are compiler-independent and are thus safer to use when multiple compilers must be supported.

Note that if you are using C++ for your Windows development, you should pay close attention to your compiler’s adherence to ANSI-standard C++, because there are different levels of support for ANSI C++ between compilers. For instance, some compilers have full support for C++ templates, whereas others do not. If you were to write a Windows program using templates, you might have a hard time porting your code from one compiler to another. Typically, though, if you are developing with ANSI-standard C and the Microsoft Windows API, your code should be 100 percent portable to any other Windows-compatible compiler.

Cross Reference:

None.

in C programming

What are the differences among HANDLE, HWND, and HDC?

Under Windows, the symbolic names HANDLE, HWND, and HDC have different meanings, as presented in Table

Symbolic names and their meanings.
-----------------------------------------------------------------------------------------------------
Symbolic Name                                Meaning
-----------------------------------------------------------------------------------------------------
HANDLE                                         Generic symbolic name for a handle
HWND                                             Handle to a window
HDC                                                 Handle to a device context
-----------------------------------------------------------------------------------------------------

It is a Windows standard to make symbolic names uppercase. As FAQ XXI.3 explains, a handle under Windows is simply a numeric reference to an object. Windows keeps track of all objects through the use of handles. Because window objects and device context objects are used quite often under Windows, they have
their own handle identifier names (HWND for window and HDC for device context). Many other standard handle names exist under Windows, such as HBRUSH (handle to a brush), HCURSOR (handle to a cursor), and HICON (handle to an icon).

Cross Reference:

None.

What is dynamic linking? in C programming

What is dynamic linking?

All Windows programs communicate with the Windows kernel through a process known as dynamic  linking. Normally, with DOS programs, your programs are linked statically. This means that your linker resolves all unresolved external function calls by pulling in the necessary object code modules (.OBJs) to form an executable file (.EXE) that contains the executable code for all functions called within your program. The Windows environment, on the other hand, provides too many functions to be linked statically into one executable program. A statically linked program under Windows would probably be several megabytes in size and horribly inefficient. Instead, Windows makes extensive use of dynamic link libraries. Dynamic link libraries (.DLLs) are somewhat like the C libraries you create under DOS, with the exception that DLLs can be loaded dynamically at runtime and do not have to be linked in statically at link time. This method has several advantages. First, your Windows executables are typically small, relying on calls to DLLs to provide runtime support. Second, Windows can load and discard DLLs on demand—which allows Windows to finetune its environment at runtime. Windows can make room for more programs if it can dynamically discard
functions that are not being used currently.

How does dynamic linking work? It is not an easy process by any means. First of all, when you link your Windows program, your compiler creates a table in your executable file that contains the name of the dynamic link library referenced and an ordinal number or name that represents that function in that dynamic link library. At runtime, when you reference a function call that is located in a dynamic link library, that DLL is loaded into memory, and the function’s entry point is retrieved from your executable’s DLL table. When the DLL is no longer needed, it is unloaded to make room for other programs.

Dynamic link libraries are typically used for large programs with many functions. You can create a DLL with your compiler—see your compiler’s documentation for specific instructions on how to carry out this task.

Cross Reference:

None.

What is the difference between Windows functions and standard DOS functions? in C programming

What is the difference between Windows functions and standard DOS functions?

Unlike most DOS functions, Windows functions are always declared as FAR PASCAL. The FAR keyword signifies that the Windows API function is located in a different code segment than your program. AllWindows API function calls are declared as FAR, because all the Windows functions are located in dynamic link libraries and must be loaded at runtime into a different code segment than the one you are running your program in.

The PASCAL keyword signifies that the pascal calling convention is used. The pascal calling convention is  slightly more efficient than the default C calling convention. With regular non-pascal function calls, the parameters are pushed on the stack from right to left beginning with the last parameter. The code calling the
function is responsible for adjusting the stack pointer after the function returns. With the pascal calling sequence, the parameters are pushed on the stack from left to right, and the called function cleans up the stack. This method results in greater efficiency.

Note  that the capitalized words FAR and PASCAL are really uppercase representations of their lowercase keywords, far and pascal. Windows simply #defines them as uppercase to comply with notation rules. Also note that DOS functions can optionally be declared as far pascal—this is perfectly legal. However, under Windows, all API functions are FAR PASCAL. This is not an option, but a mandatory requirement of the Windows environment.

Cross Reference:

XXI.1: Can printf() be used in a Windows program?

Do you need Microsoft’s Windows SDK to write Windows programs? in C programming

Do you need Microsoft’s Windows SDK to write Windows programs?

No. You do not need to purchase the Windows SDK from Microsoft to produce Windows programs— instead, most of today’s compilers include the Windows libraries, utilities, and online documentation that is replicated in the SDK.

When Windows was first introduced, Microsoft was the only vendor that had a C compiler capable of producing Windows programs. Simply purchasing the Microsoft C compiler did not enable you to create Windows programs, however. Instead, you were required to purchase the Windows SDK from Microsoft to allow your Microsoft C compiler to create your Windows programs.

With the advent of Borland C++ in 1990, the SDK was no longer required. This is because Borland licensed
the Windows libraries from Microsoft so that the developers who used Borland C++ did not need to purchase the Windows SDK. Borland also included its own Windows utilities and documentation so that a developer would be fully equipped to write Windows applications. This, in effect, started a revolution. From this point on, compiler vendors typically licensed the Windows API libraries and included them in their compilers. Even Microsoft, pressured by competition, dropped the SDK “requirement” with the introduction of Microsoft C/C++ 7.0.

Today, you can purchase pretty much any compiler that is Windows-capable without having to spend hundreds of extra dollars to buy the Windows SDK. Instead, you will find that your Windows-based compiler comes with all the necessary libraries, utilities, and documentation. In most cases, the Windows API documentation is provided online and not in hard copy to save distribution expenses.

Cross Reference:

XXI.6: Why is windows.h important?
XXI.7: What is the Windows SDK?

What is the Windows SDK? in C programming

What is the Windows SDK?

The Windows SDK (Software Development Kit) is a set of resources (software and manuals) that are available to the C programmer to construct Windows programs with. The Windows SDK includes all the Windows API function libraries, thus enabling you to link your C programs with the Windows API functions. It also includes a handful of useful utilities such as the Image Editor (for creating and modifying icons, bitmaps, and so on). It includes the executable file WINSTUB.EXE, which is linked with each Windows program to notify users that the executable is a Windows program. For instance, if you have ever tried running a Windows program from the DOS prompt, you probably have seen one of the following messages (or something similar):

This program requires Microsoft Windows.
This program must be run under Microsoft Windows.

The WINSTUB.EXE program automatically prints this message every time someone tries to run a Windows executable from a non-Windows environment. Note that the WINSTUB.EXE program is not separated, but rather is embedded into your Windows executable. It is transparent to you and the users of your programs.

The Windows SDK also includes extensive printed documentation of each Windows API function call. This documentation comes in handy when you are writing Windows programs. The Programmer’s Reference Guide details how to use each Windows API function.

With all the utilities, libraries, and documentation included with the Windows SDK, you might be inclined to think that the Windows SDK is required in order to produce Windows-based programs. See the next FAQ for a response.

Cross Reference:

XXI.6: Why is windows.h important?
XXI.8: Do you need Microsoft’s Windows SDK to write Windows programs

Why is windows.h important? in C programming

Why is windows.h important?

The windows.h header file contains all the definitions and declarations used within the Windows environment. For instance, all system color constants (see FAQ XXI.25) are defined in this header file. Additionally, all Windows-based structures are defined here. Each Windows API function is also declared in this header.

No Windows program can be created without the inclusion of the windows.h header file. This is because all Windows API functions have their declarations in this file, and without this file, your program will probably receive a warning or error message that there is no declaration for the Windows function you are calling. All Windows-based structures, such as HDC and PAINTSTRUCT, are defined in the windows.h header  file. You therefore will get compiler errors when you try to use any Windows-based structures in your program without including the windows.h file. Additionally, Windows contains numerous symbolic constants that are used throughout Windows programs. Each of these constants is defined in the windows.h header file.

Thus, the windows.h header file is extremely important, and no Windows program can exist without it. It is roughly equivalent (regarding the rules of inclusion) to the standard stdio.h file that you always include in any DOS-based C program. Not including the file can bring several compiler warnings and errors.

Cross Reference:

XXI.7: What is the Windows SDK?
XXI.8: Do you need Microsoft’s Windows SDK to write Windows programs?

What is the GDI and how is it accessed? in C programming

What is the GDI and how is it accessed?

GDI stands for Graphic Device Interface. The GDI is a set of functions located in a dynamic link library (named GDI.EXE, in your Windows system directory) that are used to support device-independent graphics output on your screen or printer. Through the GDI, your program can be run on any PC that supports Windows. The GDI is implemented at a high level, so your programs are sheltered from the complexities of dealing with different output devices. You simply make GDI calls, and Windows works with your graphics or printer driver to ensure that the output is what you intended.

The gateway to the GDI is through something called a Device Context. A device context handle is simplya numeric representation of a device context (that is, a GDI-supported object). By using the device context handle, you can instruct Windows to manipulate and draw objects on-screen. For instance, the following portion of code is used to obtain a device context handle from Windows and draw a rectangle on-screen:

long FAR PASCAL _export WndProc (HWND hwnd, UINT message,
UINT wParam, LONG lParam)
{
HDC hdcOutput;
PAINTSTRUCT psPaint;
HPEN hpenDraw;
...
switch(message)
{
...
case WM_PAINT:
hdcOutput = BeginPaint(hwndMyWindow, &psPaint);
hpenDraw = CreatePen(PS_SOLID, 3, 0L);
SelectObject(hdcOutput, hpenDraw);
Rectangle(hdcOutput, 0, 0, 150, 150);
TextOut(hdcOutput, 200, 200,
“Just the FAQ’s, Ma’am...”, 24);
...
}
...
}

In the preceding program, the BeginPaint() function prepares the current window to be painted with graphics objects. The CreatePen() function creates a pen object of a specified style, width, and color. The pen is used to paint objects on-screen. The SelectObject() function selects the GDI object you want to work with. After these setup functions are called, the Rectangle() function is called to create a rectangle in the window, and the TextOut() function is called to print text to the window.

Cross Reference:

None

How do you interrupt a Windows program? in C programming

How do you interrupt a Windows program?

As a user of Microsoft Windows, you might already know that you can terminate a Windows program in many ways. Here are just a few methods:

  •  Choose File | Exit from the pull-down menu.
  •   Choose Close from the control box menu (-) located to the left of the title bar.
  •   Double-click the mouse on the control box.
  •  Press Ctrl-Alt-Delete.
  •   Choose End Task from the Windows Task Manager.
  •   Exit Windows.

This list includes the more typical ways users exit their Windows programs. As a Windows developer, how
can you provide a way for users to interrupt your program?

If you have used many DOS programs, you might remember the key combination Ctrl-Break. This combination was often used to break out of programs that were hung up or that you could not figure a way to get out of. Often, DOS programs would not trap the Ctrl-Break combination, and the program would be aborted. DOS programs could optionally check for this key combination and prevent users from breaking out of programs by pressing Ctrl-Break. 

Under Windows, the Ctrl-Break sequence is translated into the virtual key VK_CANCEL (see FAQ XXI.17 for an explanation of virtual keys). One way you can trap for the Ctrl-Break sequence in your Windows program is to insert the following code into your event (message) loop:
...
switch (message)
{
case WM_KEYDOWN:
if (wParam == VK_CANCEL)
{
/* perform code to cancel or
interrupt the current process */
}
}
...
In the preceding example program, if the wParam parameter is equal to the virtual key code VK_CANCEL, you know that the user has pressed Ctrl-Break. This way, you can query the user as to whether he wants to cancel the current operation. This feature comes in handy when you are doing long batch processes such as printing reports.

Cross Reference:

None.

What is a handle? in C programming

What is a handle?

A handle under Windows is much like a handle used to refer to a file in C. It is simply a numeric representation of an object. Under Windows, a handle can refer to a brush (the object that paints the screen), a cursor, an icon, a window, a device context (the object that is used to output to your screen or printer), and many other objects. The handle assigned to an object is used to reference it when calling other Windows functions.

Handle numbers are assigned by Windows, usually when a Windows API function call is made in your program. Typically, variables that represent handles are prefixed with the letter h and a mnemonic representation of the object they refer to. For instance, to create a window, you might make the following Windows API call:

hwndSample =
CreateWindow(szApplicationName, /* Window class name */
“FAQ Sample Program”, /* Caption for title bar */
WS_OVERLAPPEDWINDOW, /* Style of window */
CW_USEDEFAULT, /* Initial x position */
CW_USEDEFAULT, /* Initial y position */
CW_USEDEFAULT, /* Initial x size */
CW_USEDEFAULT, /* Initial y size */
NULL, /* Window handle of parent window */
NULL, /* Menu handle for this window */
hInstance, /* Instance handle */
NULL) ; /* Other window parameters */

The Windows API function CreateWindow() is used to create an instance of a window on the screen. As you  can see from the preceding example, it returns a handle to the window that is created. Whenever this window is referenced from this point on, the handle variable hwndSample is used. Windows keeps track of handle numbers internally, so it can dereference the handle number whenever you make a Windows API function call.

Cross Reference:

None.

How do you create a delay timer in a Windows program? in C programming

How do you create a delay timer in a Windows program?

You can create a delay timer in a Windows program by using the Windows API function SetTimer(). The SetTimer() function sets up a timer event in Windows to be triggered periodically at an interval that you specify. To create a timer, put the following code in your WinMain() function:

SetTimer(hwnd, 1, 1000, NULL);

This code sets up a timer in Windows. Now, every 1000 clock ticks (1 second), your program receives a WM_TIMER message. This message can be trapped in your WndProc (message loop) function as shown here:
switch (message)
{
case WM_TIMER :
/* this code is called in one-second intervals */
return 0 ;
}

You can put whatever you like in the WM_TIMER section of your program. For instance, FAQ XXI.23 shows how you might display the date and time in a window’s title bar every second to give your users a constant update on the current day and time. Or perhaps you would like your program to periodically remind you to save your work to a file. Whatever the case, a delay timer under Windows can be very handy.

To remove the timer, call the KillTimer() function. When you call this function, pass it the handle to the window the timer is attached to and your own timer identifier. In the preceding SetTimer() example, the number 1 is used as the timer identifier. To stop this particular timer, you would issue the following function call:

KillTimer(hwnd, 1);

Cross Reference:

None.

Can printf() be used in a Windows program? in C programming

Can printf() be used in a Windows program?

The standard C function printf() can be used in a Microsoft Windows program; however, it has no usefulness to the Windows environment, and it does not produce the same result as in a DOS environment. The printf() function directs program output to stdout, the standard output device. Under DOS, the standard output device is the user’s screen, and the output of a printf() statement under a DOS program s immediately displayed.

Conversely, Microsoft Windows is an operating environment that runs on top of DOS, and it has its own mechanism for displaying program output to the screen. This mechanism comes in the form of what is called a device context. A device context is simply a handle to a portion of the screen that is handled by your program. The only way to display output on-screen in the Microsoft Windows environment is for your program to obtain a handle to a device context. This task can be accomplished with several of the Windows SDK (Software Development Kit) functions. For instance, if you were to display the string “Hello from Windows!” in a windows program, you would need the following portion of code:

void print_output(void)
{
...
hdcDeviceContext = BeginPaint(hwndWindow, psPaintStruct);
DrawText(hdcDeviceContext, “Hello from Windows!”, -1,
&rectClientRect, DT_SINGLELINE);
...
}

Put simply, all output from a Windows program must be funnelled through functions provided by the Windows API. If you were to put the line

printf(“Hello from Windows!”);

into the preceding example, the output would simply be ignored by Windows, and your program would appear to print nothing. The output is ignored because printf() outputs to stdout, which is not defined under Windows. Therefore, any C function such as printf() (or any other function that outputs to stdout) under the Windows environment is rendered useless and should ultimately be avoided. Note, however, that the standard C function sprintf(), which prints formatted output to a string, is permissible under the Windows environment. This is because all output from the sprintf() function goes directly to the string and not to stdout.

Cross Reference:

XXI.9: What is the difference between Windows functions and standard DOS functions?

What are escape characters? in C programming

What are escape characters?

Escape characters are characters designed to perform a command or task instead of being printed on the computer screen. For example, an escape character could be a character sent to a device that tells the computer screen to draw the next line in red rather than the normal white. The escape character is sent to the device that draws the red line along with the actual characters the device is supposed to draw in red. So how does the device know that the character is an escape character? Typically, the Escape key (decimal 27, octal /033) is sent just before the escape character so that the device knows that an escape character is next to arrive. After the device has the escape character, it acts on the command that the escape character represents, then resumes normal operation—taking characters and printing them on-screen. Because it usually takes two or more characters to pull off the desired command (the Escape key plus the command character itself ), this is often referred to as an escape sequence.

I know that this sounds confusing (the Escape key, followed by the escape character), but that is preciselywhy these are called escape characters. The Escape key is used to inform whoever wants to know that the next character is a command, not an ordinary character. The escape character itself (the one that comes after the Escape key) can be any character—it could even be another Escape key. The actual character that represents the desired command to occur is up to the program that is reading these characters and waiting for such commands.

An example of this is the ANSI.SYS device driver. This driver, loaded in your CONFIG.SYS file, intercepted all characters that were printed on-screen and processed these characters for escape sequences. The purpose of ANSI.SYS was to provide a way to print colored, underlined, or blinking text, or to perform higher-level commands such as clear the screen. The advantage to ANSI.SYS was that you didn’t have to know what type of monitor or display card you had—ANSI.SYS took care of that for you. All you had to do was embed the escape characters into the appropriate places in the character strings you displayed on-screen, and ANSI.SYS would take care of the rest. For example, if you printed “\033H4Hello there” ANSI.SYS would print “Hello there” on-screen in red. ANSI.SYS would see the Escape key (\033), read the command (which in this case is H4—print remaining characters in red), and print what was left (“Hello there”). 

Before ANSI.SYS, escape characters were used in the old centralized computing environments (one mainframe computer with a bunch of dumb terminals connected to it). Back in those days, the terminals had no computing power of their own and could not display graphics, and many were monochrome, unable to display color. However, each monitor did have a series of escape characters that the mainframe could send to the monitor to make it do such things as clear the screen, underline, or blink. Programmers would embed the escape characters into their character strings just as you do with ANSI.SYS, and the monitor would perform the desired command.

Today, this type of escape sequence usage has all but died out. On the other hand, many other types of character sequences could be described as escape characters that have been around for just as long, and they are still used heavily today. For example, in the section where I describe how to assign an octal or a hex value to a variable, I am using an escape character (the pair “0x” in the case of hex, and the single \ character in octal). Note that these characters do not actually use the Escape key as the “hey, here comes something special” notifier, but nonetheless they are used to denote something special about what is to immediately follow. In fact, the backslash character (\) is used quite frequently as an escape character. In C, you use \n to tell the computer to “perform a linefeed operation here.” You can use \t to perform a tab advance, and so on.

Cross Reference:

XX.23: What is octal?
XX.24: What is hexadecimal?

What is hexadecimal? in C programming

 What is hexadecimal?

Hexadecimal is the base 16 numbering system. It is the most commonly used numbering system in  computers. In hexadecimal, or hex for short, you count 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, and so on. Don’t get too bothered by the letters— they are merely single-digit placeholders that represent (in decimal) 10 through 15. Remember the rule of counting in different bases—count from 0 to the number that is one less than the base. In this case, it is 15. Because our Western numbers do not contain single-digit values representing numbers above 9, we use A, B, C, D, E, and F to represent 10 to 15. After reaching 15, or F, you can move to two decimal, rather hexadecimal, places—in other words, 10. As with octal and binary, compare hex counting to decimal counting (once again, decimal is on top):

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ...
1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, ...

Note that “10”, what we historically have called ten, in decimal is equal to “A” in hex. As with the previously discussed numbering systems, when you increase to two or three or more hexadecimal places, you are increasing by a power of 16. 1 is 160, 16 is 161, 256 is 162, 4096 is 163, and so on. Therefore, a he number such as 3F can be converted to decimal by taking (3 ´ 161) + (F ´ 160), which equals (48 + 15), or 63 in decimal (remember, F is 15 in decimal). A number such as 13F is (1 ´ 162) + (3 ´ 161) + (F ´ 160), which equals (256 + 48 + 15), or 319 in decimal. In C source code, you will see these numbers shown as 0x3F or 0x13F. The “0x” is used to show the compiler (and the programmer) that the number being referenced should be treated as a hexadecimal number. Otherwise, how could you tell whether the value “16” were decimal or hex (or even octal, for that matter)? A slight modification can be made to Table XX.22 by adding hex counting to that table (see Table XX.24).

Binary, decimal, hexadecimal conversion table.
------------------------------------------------------------------------------------------------------------
Binary                                     Decimal Value                   Binary Power                  Hex           Hex Power
-------------------------------------------------------------------------------------------------------------
0000                                       0                                                                             0
0001                                       1                                       2power of 0                   1              16power of 0
0010                                       2                                       2power of 0                   2
0011                                       3                                                                             3
0100                                       4                                        2power of 0                  4
0101                                       5                                                                             5
0110                                       6                                                                             6
0111                                       7                                                                             7
1000                                       8                                       2power of 0                   8
1001                                       9                                                                             9
1010                                       10                                                                           A
1011                                       11                                                                           B
1100                                       12                                                                           C
1101                                       13                                                                           D
1110                                       14                                                                            E
1111                                       15                                                                            F
1 0000                                    16                                     2power of 0                   10             16power of1

 I added one more count at the bottom, taking the total to decimal 16. By comparing binary to decimal to hex, you can see that, for example, ten is “1010” in binary, “10” in decimal, and “A” in hex. In the last line, sixteen is “1 0000” or “10000” in binary, “16” in decimal, and “10” in hex. What does all this mean? Because today’s 16-, 32-, and 64-bit processors all have bit widths that happen to be multiples of 16, hexadecimal fits very nicely as the numbering system for those types of computers. Another added quality is that hex is also a multiple of binary. Note that the last line of Table XX.24 shows the binary value broken into two sections (1 0000). Four binary digits (or four bits) can count up to 15 (16 unique numbers when you include zero). Four bits also equals a nibble. By looking at the table, you can see that one digit of hex can also count up to 15 (16 unique numbers because we include zero). Therefore, one hex digit can represent four binary digits. A good example is (decimal) 15 and 16. Fifteen is shown as 1111 in binary, the highest number four binary digits can count. It is also shown as F, the highest number one hex digit can count. After you go to 16, it takes five binary digits (1 0000) and two hex digits (10). The following lines convert the same numbers used earlier (0x3F and 0x13F) to binary:

3F 111111
13F 100111111

If you replace the leading spaces with zeros and break the binary digits into groups of four, it might become
a little clearer:

03F 0 0011 1111
13F 1 0011 1111

You are not required to break binary numbers into groups of four—it’s simply easier to count when you know that every four binary digits equal one hex digit. To prove that the numbers are equal, I’ll convert the binary representations to decimal (because the hex values were already converted in a previous paragraph). 111111 would be (1 ´ 25) + (1 ´ 24) + (1 ´ 23) + (1 ´ 22) + (1 ´ 21) + (1 ´ 20), which equals (32 + 16 + 8 + 4 + 2 + 1), or 63 in decimal, just as before. The number 1 0011 1111 would be + (1 ´ 28) + (0 ´ 27) + (0 ´ 26) + (1 ´ 25) + (1 ´ 24) + (1 ´ 23) + (1 ´ 22) + (1 ´ 21) + (1 ´ 20), which equals (256 + 32 + 16 + 8 + 4 + 2 + 1), or 319 in decimal. Hexadecimal and binary fit together like hand and glove.

Cross Reference:

XX.22: What is binary?
XX.23: What is octal?

Sunday 20 November 2011

What is octal? in C programming

What is octal?

Octal is base 8. Oh, no, another numbering system? Unfortunately, yes. But there is no need to describe base 8 to the level of detail that was described for base 2. To count in octal, you count 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, and so on. The following two lines count in base 8 and in base 10 side by side for comparison purposes (base 10 is on top):

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20

Notice that in base 8 (on bottom), you had to increase to two decimal, I mean octal, places after you reached
7. The second octal place is of course 81 (which is equal to 8 in the decimal system). If you were to continue counting to three octal places (100 in octal), that would be 82, or 64 in decimal. Therefore, 100 in octal is equal to 64 in decimal.
 
Octal is not as frequently used these days as it once was. The major reason is that today’s computers are 8-, 16-, 32-, or 64-bit processors, and the numbering system that best fits those is binary or hexadecimal (see FAQ XX.24 for more information on the hexadecimal numbering system). 

The C language supports octal character sets, which are designated by the backslash character (\). For
example, it is not uncommon to see C code that has the following statement in it:

if(x == ‘\007’) break;
 
The \007 happens to also be decimal seven; the code is checking for the terminal beep character in this case.
Another common number denoted in octal is \033, which is the Escape character (it’s usually seen in code as \033). However, today you won’t see much of octal—hexadecimal is where it’s at.

Cross Reference:

XX.22: What is binary?
XX.24: What is hexadecimal?

What is binary? in C programming

What is binary?

The binary numbering system is the lowest common denominator in computing. Binary is base 2. Do you remember being taught different numbering systems in elementary or high school? In one of my math classes  in grade school, I was taught base 6. You count 1, 2, 3, 4, 5, then 10, 11, 12, 13, 14, 15, then 20, and so on. At least that’s the way I was taught. In truth, you should count 0, 1, 2, 3, 4, 5, then 10, 11, 12, 13, 14, 15, and so on. By starting with 0, it becomes slightly easier to see the groupings of six digits—hence the six in base 6. Notice that you count from 0 to the number that is one less than the base (you count from 0 to 5 because 6 is the base). After you have counted to 5, you move to two decimal places. If you think about it, our base 10 (decimal) system is similar—you count up to one less than the base (9), and then you go to two digits and resume counting.

In computers, the numbering system is base 2—binary. With base 2, you count 0, 1, then 10, 11, then 100, 101, 110, 111, then 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, and so on. Contrast base 2 with base 6; in base 2, you count from 0 to 1 before going to two decimal places. Of course, the next question is “Why is base 2 used?” The reason is the transistor. The transistor is what makes

modern-day computers possible. A transistor is like a light switch. A light switch has two positions (or states),
on and off. So does a transistor. You could also say that off equals 0, and on equals 1. By doing so, you can count from 0 to 1 using a transistor (or a light switch if you want). It doesn’t seem as though you can do any serious computing with only two numbers (0 and 1), but we’re not finished yet. Suppose that you had a light switch panel that contained four light switches. Although each switch still has only two states, the four switches, when treated in combination, can have 16 unique positions, or 24 (four switches, two states each). Therefore, you can count from 0 to 15 with just four switches, as shown in Table XX.22.

Binary counting.
--------------------------------------------------------------------------------------------------------------
Switches     Decimal Value             Power
-------------------------------------------------------------------------------------------------------------
0                       0
1                       1                             20
10                     2                             21
11                     3
100                   4                             22
101                   5
110                   6
111                   7
1000                 8                              23
1001                 9
1010                10
1011                11
1100                12
1101                13
1110                14
1111                15
-----------------------------------------------------------------------------------------------------------
The table demonstrates three important points: (1) By placing the switches side by side, you can count with them—up to 15 in this case (16 total counts); (2) You can consider each switch as a decimal place, or rather a binary place, just as you can with the decimal system; (3) When each switch is considered to represent a binary place, that switch also happens to be a power of two (20, 21, 22, 23, and so on). Further, notice that in the table where a power of two is shown, the count had to add another binary place.
 
This is the same as the decimal system, in which each time you increase another decimal place, that new decimal place is a power of 10 (1 = 100, 10 = 101, 100 = 102, and so on). Knowing this, you can convert binary numbers to decimal with minimal effort. For example, the binary number 10111 would be (1 ´ 24) + (0 ´ 23) + (1 ´ 22) + (1 ´ 21) + (1 ´ 20), which equals (16 + 0 + 4 + 2 + 1), or 23 in decimal. A much larger binary number, 10 1110 1011, would be (1 ´ 29) + (0 ´ 28) + (1 ´ 27) + (1 ´ 26) + (1 ´ 25) + (0 ´ 24) + (1 ´ 23) + (0 ´ 22) + (1 ´ 21) + (1 ´ 20), which equals (512 + 0 + 128 + 64 + 32 + 0 + 4 + 2 + 1), or 743 in decimal. So what does all this nonsense get us? In the realm of computers, there are bits, nibbles, and bytes. A nibble is four bits, and a byte is eight bits. Do you know what a bit is? It’s a transistor. Therefore, a byte is eight transistors, side by side, just like the four switches in Table XX.22. Remember that if you had four switches (or transistors) grouped together, you could count to 24, or 16. You could have called that a nibble of switches. If a nibble is four transistors grouped together, a byte is eight transistors grouped together. With eight transistors, you can count to 28, or 256. Looking at it another way, this means that a byte (with eight transistors) can contain 256 unique numbers (from 0 to 255). Continue this a little further. The Intel 386, 486, and Pentium processors are called 32-bit processors. This means that each operation taken by the Intel chip is 32 bits wide, or 32 transistors wide. Thirty-two transistors, or bits, in parallel is 232, or 4,294,967,296. That’s more than 4 billion unique numbers!

Of course, this description does not explain how a computer uses those numbers to produce the fantastic computing power that occurs, but it does explain why and how the binary numbering system is used by the
computer.

Cross Reference:

XX.23: What is octal?
XX.24: What is hexadecimal?

How do you assign an octal value to a number? in C programming

How do you assign an octal value to a number?

Assigning an octal value to a variable is as easy as assigning a hexadecimal value to a variable, except that you
need to know the octal numbering system in order to know which numbers to assign.

int x;
x = \033; /* put octal 33 (decimal 27) into x */
x = ‘\033’; /* put the ASCII character whose value is
octal 33 into x */
Refer to FAQ XX.23 for detailed information on the octal numbering system.

Cross Reference:

XX.23: What is octal?

How do you assign a hexadecimal value to a variable? in C programming

How do you assign a hexadecimal value to a variable?

The C language supports binary, octal, decimal, and hexadecimal number systems. In each case, it is necessary to assign some sort of special character to each numbering system to differentiate them. To denote a binary number, use b at the end of the number (1101b). To denote an octal number, use the backslash character (\014). To denote a hexadecimal number, use the 0x character sequence (0x34). Of course, decimal is the default numbering system, and it requires no identifier.

To assign a hexadecimal value to a variable, you would do as shown here:
int x;
x = 0x20; /* put hex 20 (32 in decimal) into x
x = ‘0x20’; /* put the ASCII character whose value is
hex 20 into x */

You must know the hexadecimal numbering system in order to know what numbers to assign. Refer to FAQ
XX.24 for detailed information on the hexadecimal numbering system.

Cross Reference:

XX.24: What is hexadecimal?