text:
Windows Programming/Memory Subsystem

C programmers will undoubtedly be familiar with the stdlib memory allocation functions, malloc, realloc, calloc, etc. These functions are based off a number of other functions in the Win32 API that deal with memory segments.

Windows Memory
When talking about the memory subsystem, there are 4 distinct types of memory that Windows manages, and each type of memory has a number of different functions to allocate and free that memory.

 * Virtual Memory: The Virtual Memory subsystem allocates and manages memory by pages. This means that memory can only be allocated in blocks of 4 Kbytes (or larger, depending on processor architecture) at a time. This is a fantastically large amount of memory for most applications, and using the virtual memory functions in most programs is overkill. However, some programs do need use of entire pages for storage, so the Virtual Memory subsystem can be used for that.
 * Heap Memory: The heap is an area of memory that usually takes up a whole page, or a fraction of a page. Each process is allocated a heap immediately by windows, called the process heap. The stdlib functions such as malloc will allocate memory from this memory region. The heap can be divided up into small memory segments, for use with variables and dynamic storage.
 * Global Memory: Windows maintains at least 1 page of memory for use as general-purpose global memory. This memory can be read or written by any process running on the computer, using the global memory functions. Data in the global memory space can be shared among various programs, and items sent to the windows clipboard are generally stored in global memory (so it can be "pasted" into any program). Global memory is limited, so it should not be used without a specific need.
 * LocalMemory: Local memory has similarities to both global memory and heap memory. It is local to the process, but the memory is managed by the Windows memory manager, and not by the program. We will discuss this later.

Virtual Memory Subsystem
The virtual memory functions, as explained above, allocate memory in terms of pages. Pages are generally 4 Kbytes of memory, so most applications won't need to allocate an entire page (much less more then 1 page). The Virtual memory system is essentially the primitive function base that the other memory functions utilize to perform their tasks. For instance, the heap is comprised of 1 or more pages, and the heap functions will allocate pages using the virtual memory system when needed.

When virtual memory blocks are allocated, they are not actually being utilized, they are simply reserved by the system for future use. Other functions need to be used to segment the virtual memory pages into useful segments. Since virtual memory is allocated by pages, a number of special paging features can be used on virtual memory that can not be used on other types of memory. For instance, pages can be locked (to prevent read/write access), or they can be protected from any particular access mode (read, write, execute).

That said, there are a number of functions in the virtual memory subsystem that can be used:

 * VirtualAlloc:
 * VirtualFree:
 * VirtualProtect:
 * VirtualLock:
 * VirtualQuery:

Heap Memory
Each program is provided with a default process heap, but a process may optionally allocate any number of additional heaps, if more storage is needed. The heap functions will manage their virtual memory usage automatically, and therefore heaps can be set to grow if they are being filled up with data. If a heap is allowed to grow automatically, the heap functions will automatically allocate additional pages as needed. On the x86 architecture the heap grows in size towards higher memory addresses.

To use heap memory, a heap must first be allocated (or a handle must be obtained to the default heap). Once you have obtained a handle to a heap, you can pass that handle to the memory allocation functions, to allocate memory from that particular heap.

The stdlib memory functions (malloc, realloc, calloc, free) are all used very similarly to the heap functions, so programmers familiar with the stdlib functions may be able to figure out what many of the heap functions are doing, by examining their names:

 * HeapCreate:Allocates a heap, and returns a handle to that heap. All the other heap functions will use this handle to uniquely identify the particular heap that you are accessing. By maintaining multiple handles, your program may interface with multiple separate heaps.
 * HeapDestroy:This function closes a heap handle, and deallocates the heap memory so that other processes can use it.
 * GetProcessHeap: This function returns a handle to the default process heap. Each program gets a default heap when it is loaded, and in most applications this should be enough space to store data items.
 * HeapAlloc:Similar to the STDLIB "malloc" function, HeapAlloc allocates storage space on the heap, and returns a pointer to that space.
 * HeapReAlloc:Similar to the STDLIB "realloc" function, HeapReAlloc reallocates the storage space of a variable to be a different size.
 * HeapFree:Frees a memory object on the heap. Attempts to use the same pointer to access memory after it has been freed will cause an error.

Global Memory
Windows maintains a certain amount of global heap memory. This memory is limited compared to regular process heaps, and should not be accessed unless global memory is specially required.

When data has been written to the global memory, you don't get a pointer to that data, but instead you get a handle for that data. Once you give your data to the global memory manager, the system is in charge of it. Remember, a handle is not a pointer, and should never be used as one. The system will manage the memory in the global memory section, moving it between pages, and defragmenting it, et cetera. Data doesn't reside within a single segment

 * GlobalAlloc:
 * GlobalFree:
 * GlobalDiscard:
 * GlobalLock:
 * GlobalUnlock:
 * GlobalFlags:
 * GlobalSize:
 * GlobalHandle:

Local Memory
Local memory, in this sense, is not the kind of storage that programs utilize internally, on the stack and otherwise. Instead, Windows manages a special section of memory that it dubs to be "Local Memory", and it provides a number of functions to allocate and manage this special memory. Local memory is similar to global memory in the sense that data is written to the local location, and the system returns a handle to that data. The system will manage the data, just like in global memory. The local functions are named very similarly to the global memory functions. However, the global memory and local memory functions should never be mixed. For instance, a global memory handle should never be closed with the LocalFree function.

 * LocalAlloc:
 * LocalFree:
 * LocalDiscard:
 * LocalFlags:
 * LocalLock:
 * LocalReAlloc:
 * LocalUnlock:
 * LocalHandle:

Next Chapter

 * Multitasking

title: Windows Programming/Memory Subsystem


text:
Talk:Feminism/Tori Amos

seems to be an interesting person, but i do not really see what this has to do with feminism. the weight of the article is put on music rather than on feminism.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: Talk:Feminism/Tori Amos


text:
File talk:Wikijunior-Big Cats.pdf

Ignore my reverts, accidentally reverted to an older version (mis-clicked, these things really need to have a confirmation prompt to them), now brought the latest one back.--Konstable 06:58, 2 February 2006 (UTC)

title: File talk:Wikijunior-Big Cats.pdf


text:
Handbook of Genetic Counseling/Van Der Woude syndrome

Van Der Woude syndrome

Eiology

 * autosomal dominant
 * interstition deletion of IRF6 (interferon regulatory factor 6) on 1q32-41

Symptoms

 * lower lip pit(s) (80%)
 * watery mucoid discharge, excessive salivation
 * hypodontia
 * absent incisors (central/lateral), canines, and/or bicuspids
 * cleft lip with/without cleft palate (with/without missing second premolars)
 * cleft uvula

Treatment

 * surgical correction of the fistulas (accessory salivary glands)


text:
File:PSG Logo.jpg

Summary
Paris Saint-Germain logo.

Licensing
/Logos

title: File:PSG Logo.jpg


text:
User:Yaron ariel

Yaron Ariel HomePage

title: User:Yaron ariel


text:
Java Programming/Unicode

Most Java program text consists of characters, but any Unicode character can be used as part of identifier names, in comments, and in character and string literals. For example, π (which is the Greek Lowercase Letter pi) is a valid Java identifier:

and in a string literal:

Unicode escape sequences
Unicode characters can also be expressed through Unicode Escape Sequences. Unicode escape sequences may appear anywhere in a Java source file (including inside identifiers, comments, and string literals).

Unicode escape sequences consist of
 * 1) a backslash ' ' (ASCII character 92, hex 0x5c),
 * 2) a ' ' (ASCII 117, hex 0x75)
 * 3) optionally one or more additional ' ' characters, and
 * 4) four hexadecimal digits (the characters ' ' through ' ' or ' ' through ' ' or ' ' through ' ').

Such sequences represent the UTF-16 encoding of a Unicode character. For example, 'a' is equivalent to '\u0061'. This escape method does not support characters beyond U+FFFF or you have to make use of surrogate pairs.

Any and all characters in a program may be expressed in Unicode escape characters, but such programs are not very readable, except by the Java compiler - in addition, they are not very compact.

One can find a full list of the characters here.

π may also be represented in Java as the Unicode escape sequence. Thus, the following is a valid, but not very readable, declaration and assignment:

The following demonstrates the use of Unicode escape sequences in other Java syntax:

Note that a Unicode escape sequence functions just like any other character in the source code. E.g.,  (double quote, ") needs to be quoted in a string just like ".

International language support
The language distinguishes between bytes and characters. Characters are stored internally using UCS-2, although as of J2SE 5.0, the language also supports using UTF-16 and its surrogates. Java program source may therefore contain any Unicode character.

The following is thus perfectly valid Java code; it contains Chinese characters in the class and variable names as well as in a string literal:

title: Java Programming/Unicode


text:
User:Cynical

I DO NOT maintain this page. Please see my Wikipedia userpage instead.

title: User:Cynical


text:
File:GER Bundesliga Logo.jpg

Summary
German Bundesliga logo.

Licensing
/Logos

title: File:GER Bundesliga Logo.jpg


text:
File:Bayern Munich Logo.jpg

Summary
Bayern Munich logo.

Licensing
/Logos

title: File:Bayern Munich Logo.jpg


text:
File:Bayer Leverkusen Logo.png

Summary
Bayer Leverkusen logo.

Licensing
/Logos

title: File:Bayer Leverkusen Logo.png


text:
File:Schalke 04 Logo.png

Summary
Schalke 04 logo.

Licensing
/Logos

title: File:Schalke 04 Logo.png


text:
File:Werder Bremen Logo.png

Summary
Werder Bremen logo.

Licensing
/Logos

title: File:Werder Bremen Logo.png


text:
File:Juventus Logo.jpg

Summary
Juventus logo.

Licensing
/Logos

title: File:Juventus Logo.jpg


text:
File:AC Milan Logo.jpg

Summary
AC Milan logo.

Licensing
/Logos

title: File:AC Milan Logo.jpg


text:
File:Inter Milan Logo.jpg

Summary
Inter Milan logo.

Licensing
/Logos

title: File:Inter Milan Logo.jpg


text:
File:LFP(Spanish) Logo.jpg

Summary
La Liga logo.

Licensing
/Logos

title: File:LFP(Spanish) Logo.jpg


text:
File:Real Madrid Logo.gif

Summary
Real Madrid logo.

Licensing
/Logos

title: File:Real Madrid Logo.gif


text:
File:FC Barcelona Logo.jpg

Summary
FC Barcelona logo.

Licensing
/Logos

title: File:FC Barcelona Logo.jpg


text:
File:SuperLiga Logo.jpg

Summary
Portuguese Superliga logo.

Licensing
/Logos

title: File:SuperLiga Logo.jpg


text:
File:FC Porto Logo.jpg

Summary
FC Porto logo.

Licensing
/Logos

title: File:FC Porto Logo.jpg


text:
File:Sporting Lisbon Logo.gif

Summary
Sporting Lisbon logo.

Licensing
/Logos

title: File:Sporting Lisbon Logo.gif


text:
File:SL Benfica Logo.gif

Summary
SL Benfica logo.

Licensing
/Logos

title: File:SL Benfica Logo.gif


text:
File:PSV Logo.jpg

Summary
PSV Eindhoven logo.

Licensing
/Logos

title: File:PSV Logo.jpg


text:
File:Ajax Logo.jpg

Summary
Ajax Amsterdam logo.

Licensing
/Logos

title: File:Ajax Logo.jpg


text:
File:Feyenoord Logo.gif

Summary
Feyenoord Rotterdam logo.

Licensing
/Logos

title: File:Feyenoord Logo.gif


text:
File:Olympiakos Logo.gif

Summary
Olympiakos logo.

Licensing
/Logos

title: File:Olympiakos Logo.gif


text:
File:Panathinaikos Logo.jpg

Summary
Panathinaikos logo.

Licensing
/Logos

title: File:Panathinaikos Logo.jpg


text:
File:Rangers Logo.gif

Summary
Rangers(Glasgow) logo.

Licensing
/Logos

title: File:Rangers Logo.gif


text:
File:Celtic Logo.gif

Summary
Celtic(Glasgow) logo.

Licensing
/Logos

title: File:Celtic Logo.gif


text:
File:Shakhtar Donetsk Logo.jpg

Summary
Shakhtar Donetsk logo.

Licensing
/Logos

title: File:Shakhtar Donetsk Logo.jpg


text:
File:CSKA Moscow Logo.gif

Summary
CSKA Moscow logo.

Licensing
/Logos

title: File:CSKA Moscow Logo.gif


text:
File:Club Brugge Logo.gif

Summary
Club Brugge logo.

Licensing
/Logos

title: File:Club Brugge Logo.gif


text:
File:Anderlecht Logo.gif

Summary
RSC Anderlecht logo.

Licensing
/Logos

title: File:Anderlecht Logo.gif


text:
WebObjects/Web Applications/Development/Stateless Components

Implement isStateless in your WOComponent and you will be able to manage the state yourself:

public boolean isStateless { return true; }

Chuck Hill
There is some fairly OK information on stateless and nonsynchronizing components in Practical WebObjects. In a nutshell you need to use valueForBinding/setValueForBinding to access bound values and implement a public void reset method that nulls all instance variables. This often requires design changes to your component.

Jean-François Veillette
Sometimes for stateless component, you need to keep variables values between the 3 phases, from takeValueFromRequest all the way to appendToResponse. Since ivars in a stateless component can't handle this case (reset will be called after each phase), you have to store the information somewhere. Just use context.userInfo dictionary, and put whatever value in there. As the name imply, the value will only be good for this request only.


text:
Windows Programming/Interfacing

The Keyboard
When a key is pressed on the keyboard, the signal travels into the computer, where the kernel gets it. These signals, or "keycodes" as they are called, are raw data that needs to be translated into ASCII characters. The kernel performs this conversion, as well as obtaining other information about the keystroke. The necessary information is encoded into a message, and is sent to the currently active window. Simultaneously, the message is sent to the currently active caret.

Cursor Vs Caret
Inside Windows, there is a large terminology problem. So many different things all need to get their own names, so we can program with them, and keep everything straight. A perfect example of this is the difference between the cursor and the caret. The cursor is the graphical image that represents the mouse. It can either be an arrow for pointing, a hand, an hourglass, or an I-shaped text selector. The caret, on the other hand, is the blinking object that is used to enter text. When you type, the letter appears at the caret, and the caret moves forward by 1 space. It is important to keep these terms straight, because if you confuse them inside your program, you could have a lot of debugging to do.

Keypress Messages
There are a few keypress messages that the program can choose to handle. It is important to note that not all of these messages need to be handled in a program, and in fact it is usually a good idea to not handle many of them.

 * WM_KEYDOWN:The WM_KEYDOWN message indicates that a key has been pressed, or that it has been pressed and held down. If the key is held down, the keyboard goes into "Type-Matic" mode and generates keypress events repeatedly at a certain frequency. The kernel will generate a WM_KEYDOWN message for each of these, with the LPARAM message component containing the number of messages sent by the Kernel in succession, so that your program can choose to ignore some of the messages and not miss any of the information. In addition to the Key count, the LPARAM will contain the following information:
 * {| class="wikitable"

|- ! Bits of LPARAM !! Purpose |- | 0-15 || Key Count |- | 16-23 || Scan Code |- | 29 || Context Code |-  | 30 || Previous State |- | 31 || Key Transition |}
 * The scan code is the raw binary signal from the keyboard, which may not correspond to the ASCII value of the character. Notice that all buttons on a keyboard generate a scan code, including action buttons (Shift, ALT, CTRL). Unless you are trying to interact with the keyboard in a special way, you want to ignore the scan code. The Context Code determines if the ALT key is pressed at the same time. If the ALT key is pressed at the same time, the Context code is 1. The Previous State is the state of the button before the message was generated. The Key Transition determines whether the key is being pressed, or if it is being released. Most of the fields in the WM_KEYDOWN message can be safely ignored by most programs, unless you are trying to use Type-Matic functionality, or are trying to interface on a low level with the keyboard.

 * WM_KEYUP:This message is sent when a key that was being pressed has been released. Every key press will generate at least two messages: a Key down (when the button is pressed) and a Key Up (when the button is released). In general for most text-processing applications, the Key Up message can be ignored. The WPARAM is the value of the virtual character code, and the LPARAM is the same as for the WM_KEYDOWN message.

Accelerators
Windows users will no doubt be familiar with some of the common key combinations that are used with large windows programs. CTRL+C copies an object to the clipboard. CTRL+P prints the current document. CTRL+S saves the current document. There are dozens more, and it seems like each program has its own specific key combinations.

These key combinations are known in the Windows world as "Accelerators". A program that uses accelerators will define an accelerator table. This table will contain all the different key combinations, and the command identifier that they each map to. When an accelerator is pressed on the keyboard, the program doesn't receive the keypress messages, it instead receives a WM_COMMAND message, with the command identifier in the WPARAM field.

To translate the accelerator keypress combinations into WM_COMMAND messages, the function TranslateAccelerator needs to be used in conjunction with the message loop, as such:

while(GetMessage(&msg, NULL, 0, 0)) {   if(!TranslateAccelerator(&msg)) {      TranslateMessage(&msg); DispatchMessage(&msg); } }

The TranslateAccelerator function will automatically dispatch the WM_COMMAND message to the appropriate window.

Using the Caret
Each program may only have 1 active caret, and worse than that, the entire system may only have 1 active caret on the screen at a time. When using a caret, the programmer needs to take special care to destroy the caret when it is not in use, and to recreate the caret when needed. This can be accomplished relatively easily by creating the caret on the WM_SETFOCUS message (when the window is made active), and by destroying the caret on the WM_KILLFOCUS and WM_DESTROY messages.

The Mouse
The mouse has more messages associated, because the mouse is capable of more unique tasks than the keyboard is. For instance, the mouse has at least 2 buttons (frequently 3 or more), it often has a trackball, and it can be hovered over objects on the screen. Each of these functions of the mouse can be handled via messages, so we are going to need several messages

Mouse Messages
There are a number of mouse messages that may be handled by the program.

 * WM_LBUTTONDBLCLK: The user double-clicked the left mouse button.
 * WM_LBUTTONDOWN: The user pressed the left mouse button.
 * WM_LBUTTONUP: The user released the left mouse button.
 * WM_MBUTTONDOWN: The user pressed the middle mouse button.
 * WM_MBUTTONUP: The user released the middle mouse button.
 * WM_MOUSEMOVE: The user moved the mouse cursor within the client area of the window.
 * WM_MOUSEWHEEL: The user rotated or pressed the mouse wheel.
 * WM_RBUTTONDOWN: The user pressed the right mouse button.
 * WM_RBUTTONUP: The user released the right mouse button.

In addition, the LPARAM field will contain information about the cursor location, in X-Y coordinates, and the WPARAM field will contain information about the state of the shift and CTRL keys.

The system will handle the graphical mouse movements, so you don't need to worry that your program is going to lock up the mouse. However, the program is capable of changing the mouse cursor, and sending mouse messages to other windows, if needed.

The Timer
Timers are used to space the flow of a program via pauses, so that a group of actions can be allowed to process before another group interacts with the result. In a strict sense, the Windows Timer is not a user input device, although the timer can send input messages to the window, so it is generally covered in the same manner as the mouse and the keyboard. Specifically, Charles Petzold's famous book, "Programming Windows", treated the timer as an input device.

A common use of a timer is to notify the program of the end of a pause so that it can erase an image previously painted on the screen, such as in screensavers that display various images from one folder. The native timer function, however, is not considered accurate for games or time-critical responses. The DirectX API is preferred for games.

Each time the specified time interval assigned to the Timer elapses, the system sends a WM_TIMER message to the window associated to the Timer.

The new Timer starts timing the interval as soon as it is created by the SetTimer function. When you create a Timer you retrieve a unique identifier that can be used by the KillTimer function to destroy the Timer. This identifier is also present in the first parameter of WM_TIMER message.

Let's see the functions syntax.

UINT_PTR SetTimer(         HWND hWnd,              //Handle of the window associated  to the timer     UINT nIDEvent,          //an identifier for the timer    UINT uElapse,           //the time-out value, in ms    TIMERPROC lpTimerFunc   //the address of the time procedure (see below) );

BOOL KillTimer(         HWND hWnd,              // Handle of the window associated to the timer    UINT_PTR uIDEvent       // the identifier of the timer to destroy );

If you want to reset an existing timer you have to set the first argument to NULL, and the second to an existing timer ID.

You can process WM_TIMER message in two different ways:

- by processing the WM_TIMER message in the window procedure of the window passed as first argument.

- by defining a TimerProc callback function (fourth argument) that process the message instead of a window procedure.

Let's see the first one.

 * 1) define IDT_TIMER1 1001
 * 2) define IDT_TIMER2 1002

...

SetTimer(hwnd,                //handle of the window associated to the timer         IDT_TIMER1,           //timer identifier         5000,                 // 5 seconds timeout         (TIMERPROC)NULL);     //no timer procedure, process WM_TIMER in the window procedure

SetTimer(hwnd, IDT_TIMER2, 10000, (TIMERPROC)NULL);

...

LRESULT CALLBACK WinProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ ...  case WM_TIMER: switch(wParam) {    case IDT_TIMER1: //process the 5 seconds timer break;

case IDT_TIMER2: //process the 10 seconds timer break; }  ...

/* to destroy the timers */ KillTimer(hwnd, IDT_TIMER1); KillTimer(hwnd, IDT_TIMER2);

Now using a TimerProc.

VOID CALLBACK TimerProc(

HWND hwnd,	// handle of window for timer messages UINT uMsg,	// WM_TIMER message UINT idEvent,	// timer identifier DWORD dwTime 	// current system time );

It is called by the system to process an associated Timer's WM_TIMER message. Let's see some code.

...
 * 1) define IDT_TIMER1 1001

/* The Timer Procedure */ VOID CALLBACK TimerProc(HWND hwnd,	                    UINT uMsg,	                    UINT idEvent,	                    DWORD dwTime) {         MessageBox(NULL, "One second is passed, the timer procedure is called, killing the timer", "Timer Procedure", MB_OK);

KillTimer(hwnd, idEvent); }

...

/* Creating the timer */ SetTimer(hwnd, IDT_TIMER1, 1000, (TIMERPROC)TimerProc);

...

Timer Messages
The timer only comes with a single message, WM_TIMER, and the WPARAM field will contain the timer ID number.

Next Chapter

 * Window Creation

title: Windows Programming/Interfacing


text:
Windows Programming/Microsoft Foundation Classes

Microsoft Foundation Classes (MFC)
In essence, MFC is a SDK interface, a library consisting in a set of classes that act as wrappers around portions of the Windows API, so that C++ programmers may program Windows using some concepts of the object-oriented programming (OOP) paradigm and the C++ language (the Win32 API is based on C, as seen in C and Win32 API Section of the book). One should learn the Win32 API or at least have some ideas since some functions are absent from the MFC and would help you to better understand the SDK.

Some tools, such as Microsoft Visual Studio, are capable of automatically generating large amounts of MFC skeleton code for use in a project. Because of this, most MFC tutorials or reference materials will teach the subject using the automated Visual Studio tools, and leave out some of the gritty details. In this book where possible we try to be neutral.

MFC was first oriented mostly for enterprise-level programming projects, created in an age most code was done in C and Object Oriented Programming was only in the realm of Smalltalk.

Since the release of Visual Studio 6.0 and the MFC 6.0 little was known of the future support to the MFC since the company was favoring the .NET Framework. Version 7.0, 7.1 and 8.0 were mostly extensions to support the new OSs and to aid developers in migrating to the new framework. Since then information on the future of the MFC could be only extracted from Steve Teixeira, Microsoft Corporation, June 2005 paper - MFC: Visual Studio 2005 and Beyond, on the release of Visual Studio 2008 Service Pack 1, Microsoft seems to once again be actively supporting the MFC.

Many users today find it acceptable for a low complexity program to have a memory footprint of 30-80Mb (this is common in Java or .Net applications), low response times or "outside of your control" applications like the internet now provides. It is therefore debatable if the impact of use of MFC in small applications outweighs the benefits the libraries provides. Most of the software made specifically for Windows today uses MFC.

You should prefer the Win32 API SDK, or an alternative wrapper for it, if you do not intend to:

 * 1) Make use of a complex GUI, use the document/view architecture or complex controls. This will increase the use of system resources (memory use, exe and install size).
 * 2) Use other libraries that depend on the MFC.
 * 3) Have a complex install for your application. To distribute MFC-Based project you must build it with static MFC libraries or distribute your project with the needed MFC dlls. There is no guarantee that your customer has the required dlls for your program. Old MFC-Based programs must work with new MFC versions. They should but don't do it always. Your customer will not be very happy if after installing your project some of his old software products begin hanging.

MFC and C++
The MFC design principle is an attempt for simplification. The wrapper classes were designed so to simplify some tasks and automates others. Because of those facts, however, a certain amount of fine-tunable control was lost from the raw Win32 API or excessive automation was archived. The MFC has been recognized as having serious design flaws and inconsistencies and has not been actively maintained. The C++ language and best practices have evolved and today this constitutes a barrier for the utilization of the framework.

As MFC predates the STL standardization in to the C++ language, it implements its own versions of the STL containers, not as complete and even inconsistent, this simplistic solutions the MFC implementations tend to be faster, however you should prefers to use the STL when ever you can, it will make the code more C++ standard and permit easier portability in converting the code to multi-platform.

The MFC class library does not use Multiple Inheritance and was not designed with full support for Multiple Inheritance.
 * Multiple Inheritance

Since most MFC classes derive from CObject using Multiple Inheritance will be cause problems of ambiguity (any reference to CObject member functions will have to be disambiguated). Static member functions, including operator new and operator delete must also be disambiguated.

The best option is to avoid the use of Multiple Inheritance with MFC but take a look at Using C++ Multiple Inheritance with MFC (msdn.microsoft.com) for the needed information on how to bypass the limitations.

MFC Conventions
The MFC uses the Hungarian notation. It uses prefixes, like "m_" to indicate a member variable or "p" to indicate a pointer, and the rest of the name is normally written out in CamelCase (the first letter of each word is capitalized).

All the significant classes in MFC derive from the CObject class. The CObject does not have any member data, but does have some default functionality.
 * CObject as the Root for most MFC Classes

Using MFC
MFC requires header files that are separate from the standard  header file. The core of the MFC system requires the inclusion of . Other header files that are of some use are  (for MFC extensions), and  (for the MFC common dialog boxes).

Simply changing the header files, unfortunately, is still not enough. The MFC DLL libraries must be linked to by the project, because the DLL files contain the class definitions that will be used throughout every program. To use MFC, you must link to the MFC libraries

stdafx.h
stdafx.h is the standard include for MFC projects - that is, if you create a new MFC project, a stdafx.h will automatically be created for you. It will include all the rest of the necessary MFC header files.

theApp
Use in the header file of your application class and then include it wherever you need to use theApp.

You could try the AfxGetApp function to get a pointer to theApp, an efficient method of accessing members of your application is to make a pointer to theApp a member variable of the class which needs it -- for example:

and make sure you initialize m_pApp in the constructor or else will be accessing a NULL pointer.

and voila! Now any time you need access to your application, you got it!

Getting Started
First and foremost, it must be mentioned, that MFC is not the brand of C++ programming that "looks like C". MFC makes heavy use of the object-oriented features of C++, which can seem "dense" or even unreadable to a new C++ programmer. It is highly recommended that the reader become very familiar with C++ concepts such as classes and hierarchies now, if they are not familiar concepts yet.

The root class for MFC is the CObject class. CObject itself does not support multiple inheritance, but derivative classes do. Each application begins in a class derived from CWinApp. Every program must have a CWinApp class, and each application may only have one. CWinApp contains a number of functions for initializing an application, and controlling the instance handle (similar to the HINSTANCE member of the WinMain function). Programs that want to display a window must utilize a derivative of the CWnd class.

Basic MFC Program
We will outline here a basic MFC program that will create a simple window, but won't handle any user input. From this basic outline, we will be able to tackle more difficult subjects.

As we see here, we are immediately relying on class definitions and inheritance, so it is a good idea for readers who are not completely familiar with these topics to brush up on them before continuing.

Global Variables
MFC provides a number of global variables, that are instantiated and then utilized in the underlying MFC framework to compile your program. We can see this in our basic example code when we use the variable m_pMainWnd.

Cleanly closing an MFC application
The generic solution is PostQuitMessage([exit code]);, but take care to cleanup any lingering resources (closing documents, deallocating memory and resources, destroying any additional windows created etc), on the other hand using AfxGetMainWnd->PostMessage( WM_CLOSE ); can be a better method in some situations, since it triggers the correct shutdown sequence. This is especially important on MDI/SDI applications because it gives a chance for documents to prompt for save before exit or for the user to cancel the exit.

Wait mouse cursor
To display a busy/wait mouse cursor the MFC as added a simple helper class. Instantiate a CWaitCursor class inside a function and a wait cursor is then displayed for the duration of that function, auto destruction of the class will restore the cursor state.

Threads
As it should be expected the MFC also wraps the Win32 thread primitives in special classes and functions of its own. For generic information of threads and C++ see the C++ Programming Wikibook section on Multitasking. The MFC devised threads in worker threads and GUI threads.

Worker threads
Worker threads are especially useful to perform background tasks, or any asynchronous work that doesn't require user intervention, a print job, calculations, waiting for an event, etc. To create a worker thread, the simplest way is to implement a function that will perform the desisted work, and then create the thread with  that will use that specific function.

Exit strategy
Never use  unless you have no other choice to guarantee a thread termination. It is poor practice and dangerous.

A proper thread exit can be archived by a normal return from the thread (completion) or by signaling it to return prematurely. Since we are working on Windows and on a 32 bit bound CPUs (making 32 bits accesses atomic), it is considered safe (but not portable) to use a shared  variable to indicate to a thread to exit, any other synchronization methods can be used if available.

Since the only issue regarding thread termination is on aborting a job or exiting the program without having threads running, when dealing with worker threads, in the class that created the thread on the destructor you should signal the thread to abort and then use  to wait for the thread to terminate.


text:
Windows Programming/COM and ActiveX

People familiar with Windows have doubtless heard a number of different terms used, such as COM, DCOM, COM+, ActiveX, OLE, etc. What precisely are all these things, and how are they related?

Introduction to COM
Component Object Model (COM) is a binary-interface standard for software componentry introduced by Microsoft in 1993. It is used to enable interprocess communication and dynamic object creation in a large range of programming languages. The term COM is often used in the Microsoft software development industry as an umbrella term that encompasses the OLE, OLE Automation, ActiveX, COM+ and DCOM technologies. COM essentially lays a framework for classes to be created in any language, and to be instantiated into any other languages. A class may be written in C++, and called from VisualBasic, C# etc. Essentially, COM defines an interface that all languages must follow, if they want to participate in COM programs.

COM Libraries
COM classes, written in a compilable language (such as C++ or VisualBasic) may be compiled into DLL libraries. DLL libraries that contain COM classes are not compatible with DLL libraries written in C that contain regular C functions. However, DLL files may be compiled such that they contain both standard C functions, and COM classes.

Files that contain COM classes are referred to as "COM modules", or "COM Components". Just like with other dynamic linking applications, Windows will manage the COM interface between components automatically, so long as all the modules properly use the COM specifications.

UUID
The COM system relies on numerical identifiers known as Universally Unique Identifiers (UUID). A UUID is a 128 bit number that is essentially guaranteed to be unique COM identifier throughout the entire world. The UUID number is a hash value based on the MAC address of your primary network card (if your computer has one) and the real-time clock value of your processor. This means that the only way to generate 2 UUIDs that are identical would be to generate both at exactly the same time on exactly the same computer. Thankfully, this is impossible to do.

COM components are given a UUID number, so that they can be differentiated from all other COM components, and any given COM module can be identified by a single numeric identifier.

title: Windows Programming/COM and ActiveX


text:
Windows Programming/DCOM and COM plus

After the original versions of COM were introduced, there became a clear need to expand the functionality of the COM model, and to make some changes to the general framework. Later versions of COM were given various names, such as DCOM and COM+.

DCOM
DCOM stands for "Distributed COM", and is a protocol for linking COM components from across a local area network (LAN). DCOM allows COM components to be stored on external "COM servers", and used from other computers in the network.

COM+
COM plus = COM + MTS

.NET
When the COM design team tried to create a framework that was more easy to use then COM, more portable, and more universal, they created the .NET framework. Originally, .NET was supposed to be introduced as the next version of COM, but instead Microsoft made it into its own entity. COM development has essentially stopped, to focus more attention on the .NET platform.

Because .NET has its roots in COM, it shares many of the guiding principals of COM. First, many different OO languages can be compiled into a single intermediate language. This allows software written in C++, C#, VB.NET, and other .NET languages to be easily interfaced together to create mixed-language programs quickly. In addition, .NET has strong support for distributed computing (a la DCOM). The .NET platform is quickly being standardized, and is available on several different platforms. Therefore, .NET is not strictly a Windows-programming topic, and will likely not be covered much throughout the rest of this book.

title: Windows Programming/DCOM and COM plus


text:
Windows Programming/Obtaining HTML Help Workshop

Introduction to HTML Help
The HTML Help Workshop is a tool for creating compiled HTML help applets, that are common on many platforms. The compiled Help modules may then be used as stand-alone information sources, or as help-modules from inside a program. HTML help modules are relatively easy to create, and only require a knowledge of basic HTML to get started.

HTML Help modules can be separated by topic, and the HTML Help Workshop will automatically compile a table of contents, and create an option to search, if specified.

Obtaining the HTML Help Workshop
The HTML Help Workshop can be obtained from Microsoft as a free download. The HTML Help SDK should contain all the header files, library files, and object files that are needed to link help files into existing applications.

Download HTML Help


text:
Windows Programming/Device Driver Introduction

Types of Drivers
Windows device drivers generally come in 2 flavors: Virtual Device Drivers (VXD) and Windows Driver Model (WDM). VxD style drivers are older, and are less compatible, while WDM drivers are supposed to be fully code-compatible all the way back to Windows 98.

Driver History
In the old days of DOS, the computer was free land where anything goes. To that end, developers wrote their own hardware drivers, conforming to no specific specification or interface, using real-mode assembly code. With the advent of Windows 3.0, the operating system began to take a more hands-on approach to application management, by creating and maintaining a variety of virtual machines, to execute different programs in different processor contexts. Drivers could no longer exist as non-conformist real-mode DOS drivers, but instead had to mitigate access between multiple programs, running more or less in parallel with each other. Windows 3.0 changed the "real devices" into managed resources known as "virtual devices", and replaced the real-mode drivers with new virtual device drivers (VDD).

The Windows NT product line existed as a separate entity from the "regular" windows brand. These two operating systems were completely different in almost every imaginable way, except perhaps that the shells looked similar. Windows NT was a fully-managed operating system, and unauthorized resource accesses were blocked by the NT kernel. This meant that in Windows NT, device drivers needed to interface with the computer through specific methods, while standard windows drivers (Windows 3.0, 3.1, 3.11, 95, 98, Me) could access hardware directly, without any sort of management. The drivers for both systems at this point, were generally written in assembly language, as well.

Realizing that the market was split between Windows and Windows NT, Microsoft saw a need to introduce a single driver model, so that device drivers could be portable between Windows and Windows NT. In addition, Microsoft knew that drivers had to be writable in a higher-level language, like C, in order to be code-compatible for different hardware systems. To meet these needs, Microsoft created the Windows Driver Model (WDM). WDM drivers are compiled using the DDK, they are written in C, and they follow exacting specifications that ensure they can be executed on any windows system. This book will attempt to focus on WDM drivers, but will include notes on writing DOS TSR drivers, and VDDs as well.

Driver Issues
Device Drivers operate in kernel mode so writing, testing, and debugging drivers can be a tricky task. Drivers should always be well tested before they are installed.

Since device drivers do not operate in user mode, the user mode libraries (kernel32.dll, user32.dll, wingdi.dll, msvcrt.dll) are not available to a device driver. Instead, a device driver must link directly to ntoskrnl.exe and hal.dll which provide Native API and executive services.

Writing a Driver
Device drivers are typically written in C, using the Driver Development Kit (DDK). There are functional and object-oriented ways to program drivers, depending on the language chosen to write in. It is generally not possible to program a driver in Visual Basic or other high-level languages.

Because drivers operate in kernel mode, there are no restrictions on the actions that a driver may take. A driver may read and write to protected areas of memory, it may access I/O ports directly, and can generally do all sorts of very powerful things. This power makes drivers exceptionally capable of crashing an otherwise stable system.

The Windows platform DDK comes with header files, library files, and a command-line compiler that can be used to write device drivers in C or C++. There is no graphical interface to the DDK compiler.

Device Driver Stack
Windows implements device drivers in a highly-modular fashion, and it is important that we discuss some vocabulary before we continue the discussion of driver programming any further. The drivers necessary for any particular device are arranged in a driver stack, and are connected together internally by a singly-linked list, that starts at the bottom of the stack (the root driver), and terminates at the highest level driver. Each driver must contain at least 2 modules, a root driver, and a function driver. This combination, with some optional additions, constitute the whole of what people generally call a complete "device driver". Function Drivers will be the most common type of driver to be written, and will be of a primary focus in this wikibook.

Microsoft realized that certain classes of devices all behave similarly, and it would be a gigantic waste of time for every hardware manufacturer to have to write the entire driver code from scratch. To this end, Windows allows for a type of driver known as a class driver. Class drivers are themselves not complete function drivers, but class drivers can be dynamically linked to a regular function driver, and can simplify the development process quite a bit. It is possible to write your own class driver, but 3rd party programmers generally don't worry about it. In general, Microsoft will supply the class drivers, and driver developers will tap into those class drivers. This ensures that class drivers are fully Microsoft tested and certified, and that they are very versatile.

Another classification of driver is the filter driver. There are two general types of filter driver, an upper filter driver, and a lower filter driver. Upper filter drivers exist in the stack above the function driver, and--as their name implies--they filter the incoming I/O requests. Lower filter drivers are placed in the stack between the function driver and the root driver. Filter drivers are generally implemented as bug fixes, or as quick hack extensions for preexisting drivers.

Here is a general diagram of a driver stack:

Upper filter driver |     |   Function Driver <---> Class Driver |     | Lower Filter Driver |     |   Root driver |     |    Hardware

Buses and Physical Devices
For simplification, let us use the term "bus" to refer to any place on your computer where information can travel from one place to another. This is a very broad definition, and rightfully so: the term "bus" needs to account for everything from USB, Serial ports, PCI cards, Video outputs, etc. Each bus is controlled by its own root driver. There is a USB root driver, a PCI root driver, and so on.

Let's now consider a mythical construct known as the root bus, a structure that all other buses connect into. A root bus object doesn't actually physically exist in your computer, but it is handy to think about it. Plus, the root bus has its own driver. The root bus driver object is responsible for keeping track of the devices connected on any bus in your entire computer, and ensuring that the data gets to where it is all going.

PnP
Plug-n-Play (PnP) is a technology that allows for the hardware on the computer to be changed dynamically, and the PnP software will automatically detect changes, and allocate important system resources. PnP gets its own root driver, that communicates closely with the Root bus driver, to keep track of the devices in your system.

"Arbitrary Context"
Drivers execute in the context of whatever thread was running when windows accessed the driver. To this end, we say that drivers execute in an "arbitrary context". Therefore, it is not good practice for a driver programmer to make any assumptions about the state of the processor at the entry point to a driver. There are a few issues that arise with this, so we will discuss them here.

Floating Point Arithmetic
Drivers that want to use MMX or floating point arithmetic may find they are in for some undue difficulty. Because a driver may be entered in any context, at any time, the floating point unit may contain partial results and unhandled exceptions from the user mode program that was interrupted to call the driver. It is not enough to simply save the context and then to restore it, because any unhandled exceptions may become "unhandleable", and raise a system error or a bug check. There are only certain times when Microsoft recommends using floating point arithmetic, and we will discuss them later.


text:
Windows Programming/The DDK

What it is
The Windows DDK comes on CD with a number of different options. Specifically, the DDK is capable of writing device drivers for a number of different platforms (Win9x, WinNT, WinServer), and is capable of targeting several different processors (IA-32, IA-64, and Itanium). Installing the necessary components for every platform on every processor can take up a lot of harddisk space. In addition, the DDK comes with many examples of how to write everything from parallel port controllers to file system drivers, display drivers, and ethernet drivers. Installing all the examples can also take up a large amount of disk space.

See also: Obtaining the DDK

Checked and Free Environments
The DDK comes with a number of different batch files, that will create a suitable driver programming environment. The different batch files will create an environment to program for a specific OS/Processor combination. Each different environment will set a number of global variables that the compiler and linker will read to make decisions about the code generation. Compiling a driver using the wrong environment will lead to a driver that may not be compatible with your system (and may destabilize your computer).

For each target platform, there are two environments available: checked and free. The Checked environment is essentially a debug environment, that will add additional debugging bloat to your compiled drivers, and will perform additional error checking and warnings. The Free environment, however, does not contain any debugging information, and should only be used to compile a fully-debugged device driver.

The Tools
The DDK comes with the compiler: cl.exe, the linker: link.exe, and an assembler: ml.exe. When writing device drivers, it is recommended that you only use these particular files, and that you do not use any other versions of these programs that you may have on your computer (either from the SDK or Visual Studio). The DDK will also come with a number of header files. Some of the header files you may be familiar with, but some of them will contain function prototypes for kernel-mode libraries, that most programmers are unfamiliar with.

Opaque Members
The DDK defines a number of different data structures for use in device drivers. However, because drivers operate at kernel mode, it is important to realize that many of the fields of these structures are for use only internally to the kernel, and your driver should not alter them. These data fields are known as "Opaque" members of the structure, and should be treated as if they were a "protected" or "private" member of a C++ class. Data fields that are not explicitly mentioned in this Wikibook should be considered suspect, and if there are any outstanding questions about the availability and use of a particular data field, consult MSDN or the DDK documentation.

Warning
Device drivers should always be thoroughly debugged before installing on a system. If a faulty device driver is installed in the system, it could compromise the kernel at boot, making the entire system unstable, if not completely unusable. Uninstalling a faulty driver can be difficult, especially if you need to perform a rescue boot operation on your computer. Device drivers should be written with care, and fully debugged before installing.

title: Windows Programming/The DDK


text:
Windows Programming/Programming Shell Extensions

The Windows Shell consists primarily of explorer.exe, the graphical user interface that displays folders, icons, and the desktop. Explorer.exe is written primarily in C++, so to write extension modules is going to require OO programming. However, there are several functions, in  that a C program can use to interact with the shell to perform some basic tasks. First, we will describe some of the basic areas of your shell.

The Shell
explorer.exe, the Windows shell program, has a number of different functions that can be used to cause your program to perform tasks like the shell would. We will run over a few of them here:

ShellExecute
The ShellExecute function takes a file and a pathname as arguments, and essentially performs whatever task the shell would perform if the file in question was double-clicked. For instance, calling a ShellExecute on "MyFile.txt" would open notepad, and would display MyFile.txt. Similarly, calling ShellExecute on a hyperlink will automatically open Internet Explorer (or your default browser) and will open the specified URL.

HINSTANCE ShellExecute(HWND hwnd,                       LPCTSTR lpOperation,                        LPCTSTR lpFile,                        LPCTSTR lpParameters,                        LPCTSTR lpDirectory,                        INT nShowCmd);

 * hwnd: The handle to the parent window of the operation
 * lpOperation: The text name of the operation. These are the strings that appear in the menu when you right-click an icon. Some common values are "edit", "run", or "execute".
 * lpFile: the name of the target file
 * lpParameters: If lpFile specifies an executable file, the lpParameters field contains the commandline arguments to the executable, if any
 * lpDirectory: specifies what directory to perform the operation in
 * nShowCmd

The System Tray
The system tray is the area in the lower-right hand side of the screen that contains the clock and a number of different icons. Icons can be added to the system tray by using a simple API call. The function call to be used is the Shell_NotifyIcon function, and we will explain it here.

WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);

This function takes 2 arguments. The first argument is a message, and the second argument contains more information on the message. There are 3 messages possible:

NIM_ADD   Add a new icon to the system tray NIM_DELETE Delete an icon from the system tray NIM_MODIFY Modify an existing icon in the system tray

We can see that the second argument is a pointer to the NOTIFYICONDATA structure. This structure contains fields as such:

typedef struct _NOTIFYICONDATA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; WCHAR szTip[64]; } NOTIFYICONDATA, *PNOTIFYICONDATA;

 * cbSize: This should reflect the size of the NOTIFYICON structure. If we have a structure called "nid", we usually assign this member as follows:

nid.cbSize = sizeof(NOTIFYICONDATA);

 * hWnd: This field contains the handle of the parent window. When the notify icon is clicked, a corresponding message will be sent to this window.
 * uID: This is a numerical identifier for the icon in question. A program can have up to 12 different icons at once.
 * uCallbackMessage: This is the message that will be sent to your window. This message should be WM_USER or greater. The WPARAM field of the message will contain the uID of the icon in question.
 * uFlags: This member tells the shell which fields are valid fields. If a field does not contain any information, or if you don't want to use a particular field to set or modify a value, do not list them in the uFlags member. The possible values are NIF_ICON, NIF_MESSAGE, and NIF_TIP.
 * hIcon: a handle to the icon to be displayed in the system tray. must be a 16x16 icon.
 * szTip: A short string that contains a "tooltip" for the icon. When the mouse is hovered over the icon, the tooltip will be displayed. leave this blank, if you do not want to have a tool tip displayed.


text:
Windows Programming/Extending IE

Similarly to explorer.exe, the Microsoft Internet Explorer, iexplore.exe, can also be extended by creating a Browser Helper Object (BHO). A BHO may be a single toolbar button, an entire toolbar, or even any number of other objects in the browser. BHOs are generally programmed using C++.

title: Windows Programming/Extending IE


text:
Biblical Studies/Christianity/Hinduism

Hinduism

 * Hinduism is one of the oldest religions of the world, renowned for its outlook of the philosophy and higher thinking. While the origins of Hinduism, normally called as Sanatana Dharma or Vedic dharma, are unknown ,it is more clearly marked for its inclusiveness- it appropriates all streams of deities and thoughts including those of atheism and Tantric nature. But it has been largely accepted that Hinduism thrives on monotheism.The distinguishing features of Hinduism from other religions of the world are its deep philosophical thought(it has as many as six main divisions of philosophy grown over the last several thousands of years), a well developed ritualistic tradition along with huge families of hymns, specific social order,  beliefs in Karma theory and rebirth and finally, the belief that the ultimate purpose of man being here is to realize the Self .  The God pictured by Hinduism is a Parabrahman on one hand who is  highly apersonal and merely abides by the cosmological laws and order he himself had ordained and a personal God, sweet, compassionate and nursing and caring on the other hand. Worshiping the Parabrahman in the form of your personal God  can not only secure you good life in this world but also, can take you forward in your spiritual sojourn towards your ultimate goal of realizing the Self. Practiced by almost a billion people worldwide, it has been often a target of invaders, who kept up their attacks in the name of religion. The evolution of Hinduism can be traced from Ritualistic Vedism to philosophy to  much more later date's Bhakti Movement (the movement of Devotion to your personal God.

Christianity

 * Christianity is belief in the Creator God corroborated by testimony, plus signs and marvels and various mighty works by his self-proclaimed Son, confirming this declaration with his resurrection from the dead, Jesus of Nazareth, over 2000 years ago with the resultant world wide church guided by gifts (Hebrews 2: 4) of the Holy Spirit distributed in accordance with the will of God.
 * Love in Christianity is the first fruit of the Holy Spirit (Galatians 5: 22) to include joy, peace, longsuffering, gentleness, goodness and faith, all to inherit the kingdom of God and by love especially to serve one another.

title: Biblical Studies/Christianity/Hinduism


text:
Windows Programming/Programming Screensavers

Screensavers are graphical programs that will exercise the computer's screen while the computer is not in use, to prevent damage to the screen. Screensavers can also be very aesthetic, interesting, and entertaining however.

Requirements
Screensaver programs are essentially normal executable programs, with a few small differences:

 * 1) They have a .scr extension, instead of a .exe
 * 2) They have a ScreenSaverProc, instead of a WindowProc.
 * 3) They call DefScreenSaverProc, instead of DefWindowProc.

Also, screensavers must contain a configuration dialog box, that the shell can call when you click on the screensaver and select "properties". The last requirement is that a screensaver must have a string resource, at resource 1, with a description of the screensaver.

How they Work
Windows will send a number of different arguments to a screensaver, on the commandline, depending on what mode of operation the screensaver must take. Here are some of them:

 * /a
 * /s
 * /c
 * /p

The -a option tells the screensaver program to set the associated password, if the screensaver is selected to be password protected. The -s option tells the screensaver to run the graphics, and start saving the screen. The -c option tells the screensaver to display the configuration dialog, and the -p option tells the screensaver to run in preview mode.

The WinMain function should decode the command line, and obtain both the switch (a, s, p, c) and the handle, if specified. The Handle value will be in an ascii string, so that will need to be converted to an integer, and stored into an appropriate HWND variable. The handle provided is the handle to the parent window of the screensaver, which is usually the screensaver tab in the Windows Display dialog box. The screensaver doesn't have a parent window if it is in screensaving mode.

If WinMain has received a -s or a -p, the WinMain should call the ScreenSaverProc. If it has received the -c option, WinMain should call the Dialog box procedure function. If the screensaver receives the -a option, it should bring up a dialog to change the password.


text:
Cookbook talk:A Nice Cup of Tea

More step by step instructions? Sj

No Cream
I very strongly disaggree that cream should be added to tea. Adding cream gives it a strange taste somewhat similar to the taste of canned condensed milk. When I was young in England the milk sold then was not homogenised. The cream used to float to the top. Most people would pour off the cream and use the underlying milk to add to the tea. In my opinion Cream should NEVER be added to the tea. It spoils the taste. Even regular homogenised milk is a bit too creamy. Tea is NOT like coffee where of course cream is prefered. I do aggree with most of the rest of your description including the preference for loose tea over tea bags. It is not only the flow of the water over the tea that is significant but also that in the course of manufacture of the tea bag product the tea leaves  are more finely chopped up, often almost into a powder.

My mother  would not have Lipton tea in the house and I am often puzzled to  to understand why so many people in the U.S. seem to  think that Earl Grey is the quintesential English Tea. Earl Grey is a tea the flavour of which has been modified by the addition of a strong spice. I personally drink tea regularly and almost never drink coffee. I find the spice in Earl Grey over powers the tea and I do not like it. Frank C. Jones frankcjones@comcast.net

title: Cookbook talk:A Nice Cup of Tea