Denise Shephard
Developer Relations Group
Created: June 1994
Revised: February 1995
Editor's note: July 1997
Editor's note Please be aware that parts of this article are outdated. Be sure to consult the more up-to-date information about Window's logo requirements under "Specifications" in the Platform bin of the MSDN Library, especially "Designed for Microsoft Windows NT and Windows 95 Logo Handbook for Software Applications."
Microsoft® Windows® 95 offers developers many new features to exploit in their applications. This paper focuses on the basic requirements for a software application to be eligible to license the "Designed for Microsoft Windows 95" logo. Utilities and development tools are not discussed. Most independent software vendors (ISVs) will add even more functionality than is detailed in this article, because Windows 95 adds support for installable file systems, threads, Bézier curves, paths, plug-and-play devices, remote network access, independent color management, the Telephony API (TAPI), Messaging API (MAPI), help cue cards, file synchronization, and much more. Let's look at the basics of a great Windows 95-based application and, specifically, what you need to code for your application to qualify for the Windows 95 logo.
The Windows Logo Program started with Windows version 3.1 to help users identify products that were compatible with the Windows operating system. The audience for Windows 95 will include many first-time computer and software users. They will look for the Windows 95 logo to buy software that does more than simply run on their Windows 95-based computer. The logo will be the easiest way for users at all levels to identify products that were designed specifically to take advantage of the power and ease of use built into Windows 95. The details of the logo requirements are outlined in this paper and are intended to assist you in developing great applications for Windows 95. Happy coding!
Here are the first five requirements, applicable to all applications:
We will examine each area in detail.
The Win32 API allows a developer to target three Windows operating system platforms with a single executable. If you write your application to target Win32s®, you can use memory-mapped files, use structured exception handling, free your development from the confines of the Win16 (the 16-bit API used in Windows version 3.x) memory schemes, and step into the clean flatlands of 32-bit development. Win32 applications are preemptively multitasked on both Windows 95 and Windows NT. Win32 applications run in their own address spaces.
There are a number of Win32 compilers on the market today. Borland, Microsoft, Symantec, and Watcom all ship compilers that create Win32 executables. The "big four" compiler companies are all working on versions of their Win32 compilers that support Windows 95. Contact your compiler company today to get on the beta for the Windows 95-based version of their compiler. The requirement for Win32 in Windows 95 is to use the Portable Executable (PE) file format first introduced on the Windows NT platform. If you absolutely have to call 16-bit dynamic-link libraries (DLLs), it is acceptable—as long as the majority of your code is 32 bit. You can use thunks to accomplish this and, of course, you will want to encourage the third party that wrote the DLL to port this to the Win32 DLL as soon as possible.
An application may also be created by a tool that is a Windows 95-compatible application, but the newly created application is not of the PE format. For example, FoxPro®, dBase®, Paradox®, and others all have the ability to create applications that the author can redistribute. These are 32-bit applications that are not necessarily of the PE format but are eligible for the Windows 95 logo. A typical scenario for distributing these applications is to bundle a run-time version of some sort that enables your application to run without installing the original program. This run-time version must be of the PE format. Again, if the tool has a logo, the run-time version is Win32 PE. Your file does not need to be of the PE format, and your application is eligible for the logo, as long as it meets the other logo requirements.
A brief aside on thunking across the Windows platforms: Due to architectural implementation differences, each platform (Windows 3.1 with Win32s, Windows NT 3.x, and Windows 95) provides a different way for Windows 16-bit (Win16) code and Win32 code to interoperate. The table below is a summary of thunking on all the platforms. You will note that the most glaring omission is a common thunk for a Win32 executable to a Win16 DLL.
Method: | Universal Thunk | Generic Thunk | Flat Thunk |
Direction: | 16-bit EXE --> 32-bit DLL 32-bit EXE --> 16-bit DLL |
16-bit EXE --> 32-bit DLL | 16-bit EXE --> 32-bit DLL 32-bit EXE --> 16-bit DLL |
Platform Supported: | Windows 3.x | Windows NT 3.x | Windows 95 |
In order to write one set of code that works across Windows NT and Windows 95, the best method to use for calling a Win16 DLL from a Win32 executable depends on a number of issues: portability, speed, development time, and quality assurance time. The most portable solution is SendMessage(WM_COPYDATA...), which works on every platform and works with every combination including 16-->16 on WOW (Windows NT) and Windows 95. DDE, OLE, and Windows Sockets are all methods to look into depending on the issues listed above.
Windows 3.1 with Win32s uses the Universal Thunk, which is documented in WIN32S.HLP.
Windows NT version 3.x uses the Generic Thunk. Information on this is in the Win32 Software Development Kit (SDK) (for Windows NT 3.5) under \DOC\SDK\MISC\GENTHUNK.TXT, which describes how the Win16 DLL can call a Win32 DLL. You should also look at the Microsoft Development Library and search the Knowledge Base for "Generic Thunk."
Windows NT version 3.5 supports a Win32 DLL that can call back into Win16 code. See \Q_A\SAMPLES\INTEROP in the Windows NT 3.5 Win32 SDK, for sample thunk code that uses both the Generic Thunk and Universal Thunk in one code base.
Windows 95 documents its own thunk architecture in the Windows 95 SDK in a help file called Guide in the Help folder. The thunking documentation is at the bottom of the list (that is, not in alphabetical order).
By far the most notable change to the system is the new user interface. Developers on the one hand would like a definite set of marching orders to craft their own application, but on the other hand do not want to be told, "You must do this!" The Microsoft Windows 95 User Interface Design Guide is just that—a guide. There are no hard and fast rules. Although the new UI Guide (Development Library, Product Documentation, SDKs) is a rather hefty piece of documentation, and you will want to look into how your application can exploit the new user interface that Windows 95 sports, you can start today on user interface features that will make your application look and work seamlessly on Windows 95.
Here are the minimal user interface guidelines you will want to follow. Of course, there is much more to look at as you examine how to make your interface more accessible to the power user and the first-time computer user. First the top-level bullet points, then the juicy details.
The Windows 95 shell sports a number of new views, including large icon and small icon, so you need to supply not only a 32x32 pixel icon for your application, but you also need to supply icons for each file type your application uses and you need to include a 16x16 icon for your application and each file type. But wait—there's more. You need to register your icons using the Registry APIs. If you have used the Registry in Windows NT, this will all look quite familiar. Now is the time to stop using .INI files. Carpe diem; your users will thank you. Windows 95 also replaces the system menu with your 16x16 icon. If you do not include a 16x16 icon, the shell will shrink your 32x32 icon and probably make it look like a dead bug on a windshield
If you use common dialogs in Windows 95, especially File Open/Save As, you will get shortcuts (also called links), long filenames, and direct browsing of the network for free. If you elect to use another File Open/Save dialog, be sure it supports the following features:
At the top edge of the window, inside its border, is a special area called the title bar, which extends across the width of the window. This serves as a control point for moving the window, as well as providing access to commands that apply to the window and its associated view. Clicking the title bar with the right mouse button displays the pop-up menu for the window. (More detail on the window pop-up menu is covered in the Microsoft Windows 95 User Interface Design Guide, Chapter 7, "Menus, Controls, and Toolbars.")
The small version of the object's icon (16x16) appears in the upper-left corner of the title bar. This icon represents the object being viewed in the window. For example, it provides access (via pop-up menu) to the operations of that object.
If the object in the window represents a "tool"—that is, if it does not provide for creating, loading, and saving separate data files—it should place the small version of the application's icon in its title bar, as shown in the following illustration.
"Tool" object title bar
If the application provides for loading and saving documents or data files, the icon that represents its document or data type should instead be placed in the title bar.
Document object title bar
If the application uses the multiple document interface (MDI), the application's icon should be used in the parent window's title bar, and an icon that reflects the application data file type should be used in the child document window's title bar.
MDI application and document title bars
However, if the user maximizes the child document window so that its title bar is hidden and its title information merges with the parent, that child document's icon is displayed in the title bar, even if there are multiple documents open. If multiple child documents are open within the MDI parent window, the current active (topmost) document window's icon is displayed.
MDI title bar with document window maximized
Windows 95 has three-dimensional (3-D) color schemes. In other words, the CTL3D.DLL functionality is built in! Users have an unprecedented amount of control over the appearance of windows, colors, and fonts. With a right-click on the Desktop into Properties and screen appearance, a user can wreak havoc with the appearance of your application. Let's look at GetSysColor, GetSystemMetrics, and some common-sense guidelines for Windows 95: For starters, get and use colors and metrics from the system in dialogs and controls. Do not hard-code your shading color to gray.
Both GetSysColor and GetSystemMetrics allow you to query Windows to determine settings for fonts, colors, and so on. Most developers already check these two functions and make the appropriate choice based on the existing color scheme in the system. In Windows 95, though, it is critical that you check both of these and try to coexist with the system choices. A user can invoke one of the new 3-D color schemes with a few clicks of the mouse and at the same time change the caption bar font to 36 points! An application must be on the lookout for WM_WININICHANGED messages to appropriately color and size menus, dialogs, and static text. Do not ever rely on WIN.INI—unless you like being surprised by tech support calls.
Applications developers picked up on this idea ages ago, but up until now Windows did not take advantage of that second button. Things, as they say, have changed. First, some terms: Clicking with button 2—the right mouse button—brings up a Pop-up Menu; Control Menu, System Menu, and Window Pop-up Menu all refer to the upper left-hand corner of the window. The shell uses the right mouse button to provide commands to the user. If you have not already done this, try right-clicking in Windows 95. It's actually kind of fun. As you have discovered, there are a number of quick and accessible ways to work with whatever object you right-clicked on. Let's look at what you need to do in your application to enable this functionality.
The Microsoft Windows 95 User Interface Design Guide (hereafter "the Guide") is the last word on all of this. The file of interest is MENUSETC.DOC in the Windows 95 SDK in the UISTYLE folder (or, in the Development Library, it's Chapter 7 of the Guide ).
A pop-up menu looks just like a drop-down menu sans menu title. Pop-up menus are contextual—that is, if a user right-clicks on an icon, it doesn't make sense to include Paragraph on the menu. The Guide examples clearly show what menu items to enable under different circumstances, and offer general guidelines in ordering the items on the menus. The Guide categorizes three types of pop-up menus: Window pop-up, Icon pop-up, and Document (or Data File) Icon pop-up.
Follow the setup guidelines as outlined in the Setup Guidelines document on the Windows 95 SDK. Use the Registry APIs rather than the old GetPrivateProfileString APIs so that application-specific information is in the Registry and not added to a section in the WIN.INI or SYSTEM.INI file. If you need to store information in an .INI file, create a private one that you (of course!) delete on uninstall. This will make uninstalling your application a whole lot easier for all those MIS folks trying to manage hundreds or even thousands of users. As of the Windows 95 second beta, there is a setup/uninstall toolkit from Stirling Software, located in the Stirling folder. Look in the \helpdocs folder for more information. In the Windows 95 SDK, look under the help folder at the Guide help file: In the contents there is a setup folder that presents guidelines and specifics as to registry keys and unattended setup. Of course, as an application developer you may use whatever setup/uninstall scheme works for you, and your compiler may include setup utilities, just make sure you uninstall your application according to the guidelines in the SDK help file.
Refer to the Guide on the Windows 95 SDK for more specific information on the user interface of an application in Windows 95.
If an application uses Windows 95-only APIs, the Windows 95-only functionality should degrade gracefully when run on Windows NT version 3.5 or later. Windows 95 adds whole new areas in color management and the use of modems; these APIs will not be available on the Windows NT platform until the next version is released. Make sure you do version checking and fail gracefully on the Windows NT platform. If you are developing an application primarily aimed at Windows NT Workstation, you need to make sure your application runs on Windows 95. For instance, if you take advantage of some Windows NT functionality such as the Event Log, your application must degrade that functionality gracefully when running on Windows 95. This will save you major tech support costs and possible returns from distributors.
If the major functionality of your application relies on a low-level aspect (for example, a device driver) on Windows 95 or on Windows NT, in some cases where the driver models are different, porting your application to another platform would be onerous. For example, let's say your application relies on the tape backup functionality in Windows NT. This reliance is at a device driver level, not an API level. For you to port this application to Windows 95 would require you as an application developer to essentially write part of the operating system—the device driver support—on Windows 95. If this is the case, your application cannot run simultaneously on both Windows 95 and Windows NT due to "architectural differences" between the two operating systems, and you would not be required to be able to run on both platforms. In such a case, you will be asked by the test lab to explain why architectural differences prevent running on the secondary platform. However, most applications will not need this low-level functionality as part of their functioning, and will run well in both places.
While we are on the subject, let's examine some of the areas where Windows NT 3.5 and Windows 95 differ.
Windows NT 3.5 includes the following areas that are not supported on Windows 95. Note that the major areas of difference here are Windows NT support for World Transforms, OpenGl libraries, and additional printing support for forms. The OpenGl APIs are not listed on the chart but there are only 10 of them.
GDI Area | API |
GDI Bitmap | MaskBlt |
GDI Bitmap | PlgBlt |
GDI Info | Cancel DC |
GDI Info | GetColorAdjustment |
GDI Info | SetColorAdjustment |
GDI Info | SetGraphicsMode |
GDI Drawing | AngleArc |
GDI Drawing | ArcTo |
GDI/Printing | FindClosePrinterChangeNotification |
GDI/Printing | FindFirstPrinterChangeNotification |
GDI/Printing | FindNextPrinterChangeNotification |
GDI/Printing | PrinterMessageBox |
GDI/Printing | ResetPrinter |
GDI Other | GDIFlush |
GDI Other | GDIGetBatchLimit |
GDI Other | GDISetBatchLimit |
GDI Text | GetCharABCWidthsFloat |
GDI Transforms | CombineTransform |
GDI Transforms | GetWorldTransform |
GDI Transforms | ModifyWorldTransform |
GDI Transforms | SetWorldTransform |
GDI Print Subsystem | AddForm |
GDI Print Subsystem | DeleteForm |
GDI Print Subsystem | EnumForms |
GDI Print Subsystem | GetForm |
GDI Print Subsystem | SetForm |
Windows 95 includes the following areas that are not supported on Windows NT 3.5. Note that the only area is Independent Color Matching.
API |
CheckColorsInGamut |
ColorMatchToTarget |
CreateColorSpace |
DeleteColorSpace |
EnumerateProfiles |
GetColorProfile |
GetColorSpace |
GetICMMode |
SetCharacterizationTable |
SetColorProfile |
SetColorSpace |
SetDeviceGammaRamp |
SetICMMode |
SetOverPrint |
StartSeparation |
Windows NT 3.5 includes the following APIs that are not supported on Windows 95.
API |
DDESetQualityOfService |
GetProcessWindowStation |
GetUserObjectSecurity |
ImpersonateDDEClientWindow |
LoadCursorFromFile |
SetSystemCursor |
SetUserObjectSecurity |
ToUnicode |
Windows 95 includes the following APIs that are not supported on Windows NT 3.5.
API |
CascadeChildWindows |
CascadeWindows |
CheckMenuRadioItem |
ChildWindowFromPrintEx |
CopyImage |
DrawAnimatedRects |
DrawCaption |
DrawEdge |
DrawFrameControl |
DrawIconEx |
DrawState |
DrawTextEx |
FindMenuDefaultID |
FindWindowEx |
GetMenuContextHelpID |
GetMenuDefaultItem |
GetMenuItemRect |
GetScrollInfo |
GetShellWindow |
GetWindowContestHelpID |
LoadCursorEx |
LoadIconEx |
LoadImage |
LookupIconIDFromDirectoryEx |
MenuItemFromPoint |
PaintDesktop |
ResetDisplay |
SetMenuContextHelpID |
SetMenuDefaultItem |
SetMenuItemInfo |
SetScrollInfo |
SetShellWindow |
SetWindowContextHelpID |
TileChildWindows |
TileWindows |
TrackPopupMenuEx |
Windows NT 3.5 includes the following areas that are not supported on Windows 95. For brevity, the areas of kernel are not added to the table; differences here are seen mainly in the areas of National Language Support. All the "W" APIs are for Unicode™, which is not supported in the first release of Windows 95. Tape backup APIs are also not supported on the Windows 95 platform.
API |
BackupRead |
BackupSeek |
BackupWrite |
BeginUpdateResource |
CommandLinetoArgvW |
CompareString |
CompareStringW |
ConnectNamedPipe |
ConvertDefaultLocale |
CreateIOCompletionPort |
CreateNamedPipe |
CreateRemoteThread |
CreateTapePartition |
DefineDOSDevice |
DisableThreadLibraryCalls |
DisconnectNamedPipe |
EndUpdateResource |
EnumCalenderInfo |
EnumCalenderInfoProc |
EnumCodePagesProc |
EnumDateFormat |
EnumDateFormatProc |
EnumSystemCodePagesW |
EnumSystemLocales |
EnumTimeFormats |
EnumTimeFormatsProc |
EraseTape |
ExpandEnvironementStrings |
FoldStringW |
FreeEnvironementStrings |
FreeLibraryAndExitThread |
GetBinaryType |
GetConsoleCP |
GetConsoleOutputCP |
GetCurrencyFormat |
GetDateFormatW |
GetLocalInfoW |
GetLogicalDriveStrings |
GetNumberFormat |
GetProcessAffnityMask |
GetProcessWorkingSetSize |
GetQueuedCompletionPortStatus |
GetStringTypeW |
GetSystemTimeAdjustment |
GetTapeParameters |
GetTapePosition |
GetTapeStatus |
GetThreadLocale |
GetThreadTimes |
GetTimeFormatW |
HeapCompact |
HeapLock |
HeapUnlock |
HeapValidate |
IsTextUnicode |
IsValidLocale |
LoadLibraryEx |
LockFileEx |
MoveFileEx |
PrepareTape |
QueryPerformancCounter |
QueryPerformanceFrequency |
ReadFileEx |
SetConsoleCP |
SetConsoleOutputCP |
SetProcessShutdownParam |
SetSystemTimeAdjustment |
SetTapeParameters |
SetTapePosition |
SetThreadAffinityMask |
UnlockFileEx |
UpdateResource |
VirtualProtectEx |
WriteFileEx |
WriteTapemark |
Windows 95 includes the following areas that are not supported on Windows NT 3.5. This is a very short list; major areas are COMM/Modem APIs and the new system power APIs, all two of them.
API |
BuildCommDCB |
BuildCommDCBAndTimeout |
ClearCommBreak |
ClearCommError |
EnumCommDevices |
EscapeCommFunction |
GetCommEvent |
GetCommMas |
GetCommModemStatus |
GetCommPorperties |
GetCommState |
GetCommTimeouts |
GetSystemPowerStatus |
ModemAnswer |
ModemClose |
ModemCommand |
ModemDial |
ModemGetCommand |
ModemHangUp |
ModemOpen |
PurgeComm |
SetCommBreak |
SetCommMask |
SetCommState |
SetSystemPowerStatus |
SetupComm |
TransmitCommChar |
WaitCommEvent |
For a look at the various system limitations in GDI/Kernel/User, please consult the Introduction help file on the Windows 95 SDK.
Support long filenames in your application, and use long filenames for displaying all document and data filenames in the shell, in title bars, in dialogs and controls, and with icons.
Open and save files with long names and display them in your title bars. If you use the common dialogs, you get lots of functionality for free with Open and Save: You get shortcuts, both enumeration and resolution, direct browsing of the network, shell operations such as drag and drop of files, and creation of new folders via shortcut menus from the right mouse button. To hide .3 extensions in your application, let the shell hide the extension for you; the system defaults to hide MS-DOS file extensions for file types but (as with almost everything else in Windows 95) the user can turn this off and enable showing .3 extensions on a per-file basis. There are some cases where hiding .3 extensions may not be desirable, such as when you deal with multiple files with the same name that get saved as different file types. You can use your judgment as to whether this is the case in your application.
Call SHGetFileInfo to determine the display name of the application. SHGetFileInfo is in Shell2.H. The call looks something like this:
include <shell2.h>
SHFILEINFO sfi
if (SHGetFileInfo (szFileName, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME))
sfi.szDisplayName() now contains the display name you should use for szFileName. You need to add code to check for the existence of the filename.
There you are designing the next great application and you say to yourself, "Well at least I don't have to worry about that Plug and Play stuff, that's for the hardware folks." Not! Software applications can Plug-and-Play–enable themselves to respond intelligently to dynamic hardware changes in the system. The good news is there are no APIs to worry about, just a few messages to watch for. Unfortunately, Plug and Play will not be supported on Windows NT until the next generation after version 3.5. However, because you are only looking for a handful of messages, your code will run fine on the Windows NT platform with no modification. Following are the messages:
In addition to requirements 1 through 5, any applications that use files need to incorporate requirements 6, 7, and 8, which are enumerated in the following sections. (Excluded from these requirements are applications that run exclusively in full-screen mode, that is, applications that cannot be windowed or minimized. Generally, this refers to applications without minimize and maximize buttons or those that use the full-screen APIs.) File-based applications include Open/Save/Close functionality, typically on the File menu of the application. However, this definition is not completely black and white. For contrast, let's consider some non-file-based applications.
A non-file-based application is one that is not primarily used to create, edit, and save files (but note that file operations may be commonly performed ancillary tasks). A direct example of this might be a multimedia reference title, a game, or an application such as Terminal or Clock, which for the most part does not save files in any way, and if it does, it's done as a facility for saving (for example, user profiles). A somewhat less direct example is the following: An investment-analysis application might allow a user to perform a query to determine a common stock's current price, then analyze the stock's historical price performance by creating various descriptive statistics, charts or graphs, which the user might save. Although a file might be created and saved in this latter example, editing files is not the primary purpose of the application. Rather, it is a simple convenience provided by the application. All the examples in this paragraph are of applications that are not primarily "file-based," thus, the following three requirements do not apply to them.
Applications such as WordPad and Paint do work with files, and do function primarily to allow the user to create, edit, and manipulate files, and therefore do need to support the requirements for "file-based" applications in order to be eligible for the Windows 95 logo.
Whew! Now let's look specifically at these last three requirements. Your application must:
If your application uses files, it should support Universal Naming Convention (UNC) paths. The goal of Windows 95 is to be a universal network client and connect anytime, from anywhere, to just about anything. Your application does not need to be network-aware per se, but it does need to work seamlessly in a network environment. Providing support for long filenames will set you up nicely for long filenames in the shell and on network operating systems such as Novell® NetWare®. UNC paths allow logical connections to network devices without the need to specifically reference a network drive letter. The system will be able to locate the network server and path with the UNC name even over a modem connection.
To ensure that your application will work seamlessly in a network environment, open and save files with UNC paths to enable direct network browsing. Display the friendly form in your title bar (for example, "My file on Darth Vader"). Remember to use correct sharing modes so multi-user scenarios work.
Windows 95 is OLE 2.0-crazed. This is good for application users; now that OLE 2.0 class libraries and tools are widely available, it is also good for developers. Application users love drag and drop. Your application needs to be drag-and-drop enabled; fortunately, there are samples in the OLE 2.0 SDK to get you started. If you have already implemented cut-copy-paste, the work to implement drag and drop is not too difficult.
Applications that work with files should:
The application should either be an OLE Windows object container, or it should provide a containable and linkable Windows object. (There may be exceptions where embeddable and linkable don't both apply.) The application's use of OLE should conform to the OLE Component Object Model.
An OLE Windows object container application is one that can embed and link a standard OLE object. Cl2Test from the OLE SDK is a sample container.
The test case is to embed and link the geometric shape object from the OLE SDK Server Test sample application (SR2TEST.EXE). This includes editing and updating according to OLE UI guidelines for embedded and linked objects.
In-place activation (sometimes called visual editing) is not required for the Windows 95 logo. As an ISV, you need to evaluate this feature and determine if it will enhance your application.
An OLE Windows object can be embedded in and linked to a standard OLE Windows object container.
The test case is to embed and link your object into the OLE SDK Container Test sample application (Cl2Test), or the OleClient MFC sample application. This includes editing and updating according to OLE UI guidelines for embedded and linked objects.
In-place activation (sometimes called visual editing) is not required for the Windows 95 logo. As an ISV, you need to evaluate this feature and determine if it will enhance your application.
To support drag and drop, a Windows object should support being dragged to and dropped upon Windows drop targets, that is, it should support the IDropSource:: interface.
The test case is to drop your object on the SVROUTL sample in the SDK (which supports IDropTarget::).
To support drag and drop, a Windows object container should be an OLE Windows object drop target, that is, it should support the IDropTarget:: interface.
The test case is to accept an object dragged from CNTRLOUTL sample in the SDK (which supports IDropSource::).
If the application is a Windows object container, it should support the OLE structured storage compound file format.
A Windows object container application should store its data (and the data of any embedded Windows objects) as an OLE compound file.
If the application uses OLE compound files, the File Summary Information should be provided.
The test is that the Summary Information be usable and complete as presented by the Windows 95 shell. The fields are as follows:
Author |
Comments |
Create Time/Date |
Keywords |
Last Printed |
Last Saved By |
Last Saved Time/Date |
Name of Creating Application |
Number of Characters |
Number of Pages |
Number of Words |
Revision Number |
Security |
Templates |
Thumbnail |
Total Editing Time |
Please refer to the OLE 2.0 Reference manual for further documentation.
Windows 95 will ship with the Microsoft Mail client, and since more and more of your customers are using e-mail, you can add the Send Mail command as a menu option. Of course, CMC API enables you to do all kinds of messaging support, but the minimum effort you need to expend here is to add the Send Mail command using MAPI. Depending on what type of application you have and your target audience, you may want to look a bit deeper into Mail functionality. If the majority of your customers do not use a mail system that supports MAPI then you will want to add CMC support.
CMC API supports the XAPIA industry-standard cross-platform messaging API effort. Enabling your application to include Send Mail as a menu option will work regardless of the messaging or network system that is running on the back-end. All you need to be concerned with are the client APIs, unless you are a vendor who writes back-end mail systems, in which case you should look into writing a Service Provider Interface to XAPIA. Applications that work with files can add a Send command on the File menu by calling MAPISendMail. There are MAPISendMail examples in the Microsoft Development Library in the MAPI SDK samples and on the Windows 95 SDK. CMC sample code is also included in the MAPI SDK, available on the Development Platform.
Please see Appendix A for a code sample that implements Send Mail support.
There are a few special requirements for utilities and development tools. For details, please see the document on the Windows 95 Logo Technical Criteria, available in the locations listed below. In general, these locations will always include the most up-to-date information available on the Windows 95 logo:
Access the Microsoft Developer Solutions Phone-Fax service by calling (800) 426-9400. Choose option 2 for Developer Solutions, then option 1 for the Faxback service; or dial (206) 635-2222. You can request a complete index of available documents. You can also choose Document #130 for specific information on the Windows 95 Logo Program. The document you are reading is Document #131. Documents on the Windows Logo are numbered in the 130s range.
The WinNews Newsletter: To receive regular monthly updates on the progress of Windows 95, subscribe to Microsoft's WinNews Electronic Newsletter. These updates are e-mailed directly to you, saving you the time and trouble of checking our WinNews servers for updates. To subscribe to the Electronic Newsletter, send Internet e-mail to enews@microsoft.nwnet.com with the words SUBSCRIBE WINNEWS as the only text in your message.
Cluts, Nancy. "Getting Ready for Windows 95", Microsoft Development Library (Technical Articles, Windows (32-bit) Articles, Window Manager Articles).
Steele, Tammy. "How to Adapt an App for Chicago: Requirements for the New Windows Logo," Microsoft Development Library (Books and Periodicals, Microsoft Developer Network News, 1994 volume 3).
Microsoft Windows 95 User Interface Design Guide, Microsoft Development Library (Product Documentation, SDKs, User Interface Design Guide).
The following code implements a function callable from an application to send documents through the underlying messaging system. The code uses a single simple MAPI function.
#include "_MAILIT.H" // Internal function declarations, constants, etc
#include "MAILIT.H" // Public function definition
DoSendMail()
// Parameters
//hOwnerWnd Owner window of any message box or dialog we need to display.
//pszFiles Pointer to string containg the files to send. The files must
// have a fully qualified path and file name. The string could have multiple
// files separated by a semicolon";". The filenames may be long file names.
//fAsynchWork If this is TRUE, the message submission will be made on a
// separate thread other than the thread where the DoSendMail was called. With
// this flag, the function returns immediately after the working thread has been
// created. If this is FALSE, the call is synchronous and it will return when
// the message is submitted to the messaging subsystem.
//Purpose
//This function is called by apps to send files to a mail recipient. The
// attachments can be of any size. The underlying messaging system will ask for
// credentials of the recipients. When the send note is displayed, other options
// can be added or modified. Also at that time other types of attachments can be
// added (for example, OLE objects).
//Return Value None
void DoSendMail (HWND hOwnerWnd, LPTSTR pszFiles, BOOL fAsynchWork)
{
// Initialize the MAPI library and function pointers
if (!InitMAPIFunctions (hOwnerWnd))
{
// Can't continue, bail out.
return;
}
TCHAR szFilePaths[1024], szFileNames[1024], szTmpName[256];
szFileNames[0] = szTmpName[0] = NULL;
// Copy file path string to local buffer (to preserve the original
// string intact)
lstrcpy (szFilePaths, pszFiles);
// The filenames must be separated by semi-colons, so parse the string for
// the sub-strings.
LPTSTR pszFileNameToken = STRTOK (szFilePaths, TEXT(";\n"));
while (pszFileNameToken)
{
// Strip leading blanks from name.
while (*pszFileNameToken == ' ')
{
pszFileNameToken++;
}
// Get the filename (long filenames are supported).
GetFileTitle (pszFileNameToken, szTmpName, 256);
// Append to string of filenames (no paths).
lstrcat (szFileNames, szTmpName);
lstrcat (szFileNames, TEXT(";"));
// Get the next sub-string in the files string.
pszFileNameToken = STRTOK (NULL, TEXT(";\n"));
}
// Call MAPI to send the document. This function always prompts with a
// dialog box so that the user can provide recipients and other sending
// options. The function tries to establish a session from the messaging
// system's shared session. If no shared session exists, it prompts for
// logon information to establish a session. Before the function returns, it
// closes the session.
ULONG ulResult = MAPISendDocuments ((ULONG)hOwnerWnd,
TEXT(";"),
pszFiles,
szFileNames,
0);
if (ulResult)
{
// Oops, there was a problem. What was it?
wsprintf (szFileNames,
TEXT("Failed to send the documents. Error: %d"),
ulResult);
MessageBox (hOwnerWnd, szFileNames, NULL, MB_OK);
}
// Unload the MAPI library
FreeMAPILib();
}
///////////////////////////////////////////////////////////////////////////////
// InitMAPIFunctions()
// Parameters
// hOwnerWnd Parent window on which any message will be displayed.
// Purpose
// Loads the DLL of simple MAPI functions and sets up a pointer to each
// function we will use.
// Return Value
// TRUE if sucessful, FALSE otherwise
BOOL WINAPI InitMAPIFunctions (HWND hOwnerWnd)
{
// Change the error mode temporarily so we don't get the system default
// message box.
UINT uErrorMode = SetErrorMode (SEM_NOOPENFILEERRORBOX);
g_hMAPILib = LoadLibrary (TEXT("MAPI32.DLL"));
// Reset it to normal.
SetErrorMode (uErrorMode);
// Do we have a valid handle?
if (!g_hMAPILib)
{
MessageBox (hOwnerWnd,
TEXT("Failed to load the MAPI DLL"),
NULL,
MB_OK);
return FALSE;
}
// Initliaze the function pointers.
pfnMAPISendDocuments = (PFNMAPISENDDOCUMENTS)GetProcAddress (g_hMAPILib,
MAPISENDDOC_NAME);
// Do we have valid pointers for the function entry points?
if (!pfnMAPISendDocuments)
{
// Something went wrong, fail the call.
MessageBox (hOwnerWnd,
TEXT("Failed to get function entry point in the MAPI DLL"),
NULL,
MB_OK);
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// FreeMAPILib()
// Parameters None
// Purpose
// Frees the the library of the MAPI functions and sets the instance
// handle back to NULL.
// Return Value None
void WINAPI FreeMAPILib()
{
// Do we have a valid handle?
if (g_hMAPILib)
{
// Free the library (decrease the reference count) and reset the handle.
FreeLibrary (g_hMAPILib);
g_hMAPILib = NULL;
}
}
// End of file for MAILIT.CPP.
// Begin file _MAILIT.H
// File Name
// _MAILIT.H
// Description
// This file includes the standard WINDOWS modules and the header files for
// the data structure declaration of MAPI message and file attachments. We also
// declare the prototypes function pointer for entry points in the MAPI DLL.
#ifndef __MAILIT_H
#define __MAILIT_H
#define STRICT // For parameter validation (in Windows.H).
#include <WINDOWS.H>
#ifdef UNICODE
// UNICODE prototype of the entry points in the MAPI DLL.
#error This sample does not compile for UNICODE yet
// UNICODE version of the MAPI entry point.
#define PFNMAPISENDDOCUMENTS PFNMAPISENDDOCUMENTSW
// UNICODE name of the entry points for the simple MAPI function.
#define MAPISENDDOC_NAME TEXT("MAPISendDocumentsW")
#else
// ANSI prototype of the entry points in the MAPI DLL.
typedef ULONG (*PFNMAPISENDDOCUMENTSA)
(ULONG ulUIParam,
LPSTR pszDelimChar,
LPSTR pszFilePaths,
LPSTR pszFileNames,
ULONG ulReserved);
// ANSI version of the MAPI entry function points.
#define PFNMAPISENDDOCUMENTS PFNMAPISENDDOCUMENTSA
// ANSI name of the entry points for the simple MAPI functions.
#define MAPISENDDOC_NAME "MAPISendDocuments"
#endif // UNICODE
// Declaration (and initialization) of function pointer.
static PFNMAPISENDDOCUMENTS pfnMAPISendDocuments;
// Wrapper macros to clarify coding.
#define MAPISendDocuments (*pfnMAPISendDocuments)
// Prototypes of functions in this DLL.
BOOL WINAPI InitMAPIFunctions (HWND);
void WINAPI FreeMAPILib();
// Global variables used across functions (must be initialized to null).
static HINSTANCE g_hMAPILib = NULL;
// Character-set neutral macros for the C run-time functions for string
// manipulation.
#ifdef UNICODE
#define STRTOK wcstok
#else
#define STRTOK strtok
#endif
#endif // __MAILIT_H
// End of file for _MAILIT.H.