home *** CD-ROM | disk | FTP | other *** search
/ CICA 1992 November / CICA_MS_Windows_CD-ROM_Walnut_Creek_November_1992.iso / win3 / misc / port32 / port32.txt < prev   
Text File  |  1991-08-21  |  46KB  |  1,070 lines

  1. Microsoft Corporation
  2.  
  3. Programming Considerations For 32-Bit Windows Operating Systems
  4.  
  5. August, 1991
  6.  
  7. Abstract
  8.  
  9. The first prerelease MicrosoftR WindowsTM 32-Bit Software
  10. Development Kit will be available soon.  During the beta testing
  11. of Windows 3.1, developers can update application source code and
  12. make changes that will result in a robust Windows 3.1 application
  13. as well as prepare the application for transition into the the
  14. full 32-bit environment provided by the Windows 32-Bit API.  This
  15. paper is not a call to start creating 32-bit source code but
  16. rather a highlight of the changes that will benefit updating
  17. source code for Windows 3.1 now and Windows 32-Bit applications
  18. later.
  19.  
  20.  
  21. 1. Goals of MicrosoftR WindowsTM 32-Bit API
  22. The creation of the Windows 32-Bit application programming
  23. interface (Windows 32 API) focused on five goals:
  24.  
  25.   1. Provide a 32-bit migration path for existing Windows
  26.      applications
  27.  
  28.   2. Make porting a Windows application to Windows 32 as easy as
  29.      possible
  30.  
  31.   3. Create an efficient mapping layer to run Windows 3.x
  32.      binaries on Windows 32-Bit systems
  33.  
  34.   4. Support a single source code base for creating Windows 3.x
  35.      and Windows 32-Bit binaries
  36.  
  37.   5. Offer an identical Windows 32-Bit API on both Windows NT-
  38.      mode and a future release of Windows Enhanced-mode
  39.  
  40. To achieve these goals, Microsoft derived the Windows 32-Bit API
  41. from the existing Windows 3.1 API, disallowing arbitrary name
  42. changes of data types, functions, and structures. At first
  43. glance, a Windows 32-Bit application is indistinguishable from an
  44. existing Windows 3.0 or 3.1 (hereafter referred to as Windows
  45. 3.x) application, both from an end-user's perspective and from a
  46. quick inspection of the source code.  A native Windows 32-Bit
  47. application (unlike its cousin which uses the Windows 3.x API)
  48. can take full advantage of large linear memory allocation,
  49. multiple threads for background tasks and calculations, local and
  50. remote interprocess communication via named pipes, and other
  51. features detailed in The Windows 32-Bit API: An Overview.
  52.  
  53. The Windows 32-Bit API will first appear on Windows NT for
  54. uniprocessor and multiprocessor Intel386TM and Intel486TM systems
  55. and for new RISC-based systems.  A future version of Windows
  56. Enhanced-mode will also support the Windows 32-Bit API.  All
  57. Windows 32 features are supported by both Windows NT-Mode and a
  58. future release of Windows Enhanced-mode, including linear address
  59. space, threads, and preemptive multitasking. Windows 32-Bit
  60. applications running Windows Enhanced-mode or Windows NT-mode
  61. will be binary compatible with IntelR processors and source
  62. compatible with Windows NT running on RISC processors.
  63.  
  64.  
  65. This paper concentrates on two aspects of Windows 32:
  66.  
  67.   1. Steps that developers can taken today while working on
  68.      Windows 3.1 applications to better support binary
  69.      compatibility of these applications on Windows NT;
  70.  
  71.   2. Techniques that developers can use to create Windows code
  72.      that is more portable and  that will make it easier to
  73.      create Windows 32-Bit versions of the application when
  74.      Windows 32-Bit Software Development Kits are available.
  75.  
  76.  
  77. 2. Binary Compatibility
  78.  
  79. Windows 32-Bit systems will be able to run existing Windows 3.x
  80. applications with interoperability via dynamic data exchange
  81. (DDE), object linking and embedding (OLE), metafiles, and the
  82. clipboard with other Windows 3.x applications and with native
  83. Windows 32-Bit applications. Windows 3.x applications and Windows
  84. 32-Bit applications will exist side-by-side on the same display
  85. rather than running in separate screen groups.  Windows 3.x
  86. applications will be fully compatible with Windows NT if
  87. developers follow these rules:
  88.  
  89.   *  Ensure that Windows 3.x applications run in
  90.      Standard/Enhanced mode.
  91.  
  92.   *  Use published Windows 3.x APIs, messages, and structures.
  93.  
  94.   *  Do not modify WIN.INI directly; use a profile string API.
  95.  
  96.   *  Restrict direct port I/O (only standard devices).
  97.  
  98.   *  Do not directly access the disk controller; doing so is a
  99.      security violation.
  100.  
  101.   *  Do not modify the system date and time; doing so is a
  102.      security violation.
  103.  
  104. Windows NT provides U.S. government-level security capabilities
  105. that preclude allowing applications direct access to hardware.
  106. Rules 4-6 above do not apply to future versions of Windows
  107. Enhanced-mode that will support the Windows 32-Bit API.  The
  108. restriction is a feature specific to Windows NT.
  109.  
  110. 2.1 Design Requirements
  111.  
  112. Mapping-layer technology has been offered in the past to allow
  113. Windows-based  applications to run on OS/2R.  Past solutions such
  114. as Windows Libraries for OS/2 (WLO) required special runtime
  115. libraries and DLLs before Windows-based applications could run on
  116. OS/2.  ISVs must ship WLO mapping-layer DLLs along with their
  117. applications, which complicates distributing and installing them.
  118. This approach is unacceptable on Windows 32-Bit systems.
  119.  
  120. To achieve binary compatibility and high performance on Windows
  121. 32-Bit systems, developers of  Windows version 3.x applications:
  122.  
  123.   *  do not need to recompile the source code,
  124.  
  125.   *  do not need to use special runtime libraries,
  126.  
  127.   *  and do not need to develop or acquire special tools to make
  128.      executables                                              
  129.      compatible.
  130.  
  131. The ability to run Windows 3.x binaries lets a developer update
  132. to Windows 32-Bit systems and continue to use existing Windows
  133. 3.x applications as well as  native Windows 32-Bit applications
  134. as they become available.  Native Windows 32-Bit applications
  135. will take advantage of the higher performance linear 32-bit
  136. addressing and enormous capacity increase for data processing.
  137. Microsoft will encourage Windows developers to test their
  138. products on pre-release versions of Windows NT through a Windows
  139. NT beta test program.
  140.  
  141. 2.2 Supported Features
  142.  
  143. The following is a list of many of Windows 3.x features
  144. inherently supported on Windows 32-Bit systems.  This list shows
  145. that existing Windows-applications can be binary compatible with
  146. future Windows 32-Bit systems with little work on the part of
  147. developers.  It also illustrates that complex windowing,
  148. graphics, and low-level operating system reliance by Windows 3.x
  149. binaries will be completely supported.
  150.  
  151. Major user interface features that are fully supported include:
  152.  
  153.   *  Multiple document interface messages and default message
  154.      handling
  155.  
  156.   *  Resource files (e.g. dialog boxes, menus, accelerator
  157.      tables, and user-defined resources)
  158.  
  159.   *  DDE messages and the DDE manager library (DDEML) API
  160.  
  161.   *  Windows version 3.1 OLE
  162.  
  163.   *  Metafiles
  164.  
  165.   *  Clipboard data exchange
  166.  
  167. Major graphical interface features that are fully supported
  168. include:
  169.  
  170.   *  TrueType and TrueType APIs
  171.  
  172.   *  Windows 3.x icons and cursors in existing format
  173.  
  174.   *  Bitmaps (BMPs) and device independent bitmaps (DIBs)
  175.  
  176.   *  Printing by means of native Windows 32-Bit printer drivers
  177.  
  178. Base system functionality includes support for:
  179.  
  180.   *  Shared memory for interprocess communication
  181.  
  182.   *  NetBIOS and Microsoft LAN Manager for DOS named pipe support
  183.  
  184.   *  MS-DOS 5.0 interfaces (called with DOS3Call or INT21)
  185.  
  186. 2.3 Methods to Achieve Binary Compatibility
  187.  
  188. A Windows 3.x application must meet several requirements to be
  189. binary compatible on Windows NT; most relate to security.
  190. Applications do not "own" the machine as they do in Windows 3.x.
  191. As discussed above, directly accessing hardware (without a device
  192. driver) is a severe security violation on Windows NT. If direct
  193. hardware manipulation were supported, aberrant or malicious
  194. applications could affect the hardware causing system crashes or
  195. system instablity. This possibility is not acceptable in mission
  196. critical applications or on network servers, which Windows NT is
  197. designed to support.
  198.  
  199. The Windows 32-Bit system will employ a registration database
  200. which will maintain all system and application configuration
  201. information. Files such as WIN.INI will no longer exist in the
  202. file system; instead, calls to the profile API (for example,
  203. GetProfileString) will be routed to the database. Therefore,
  204. applications should not attempt to create or modify *.INI files
  205. directly by means of file I/O API. The Windows 3.x profile APIs
  206. should manipulate all profile information. Installation programs
  207. that create private installation files should be modified to use
  208. the profile API.
  209.  
  210. Applications must be compatible with Windows 3.x Standard- or
  211. Enhanced-mode.  Windows 32-Bit systems will not support Windows
  212. real mode.  Applications should use only published Windows 3.x
  213. APIs, messages, and structures.
  214.  
  215. 3. Portable Coding Techniques
  216.  
  217. With the release of Windows 3.1, many applications are being
  218. updated to add support for features such as OLE and to take
  219. advantage of TrueType.  Because Windows programmers are already
  220. scrutinizing their applications' sources, now is a convenient
  221. time to prepare the code for the future, which offers a 32-bit
  222. environment with powerful new features.
  223.  
  224. The discussion below concentrates on the important issues that
  225. affect the portability of existing Windows source code to Windows
  226. 32-Bit.  Although this list may seem long and detailed,  all
  227. recommendations are useful for creating robust Windows 3.1
  228. applications.  In addition, applications will be more portable,
  229. and it will be easier to create native Windows 32-Bit
  230. applications quicker when Windows 32-Bit Software Development
  231. Kits are available.
  232.  
  233.  
  234. Rules for Writing Portable Windows 3.x/Windows 32-Bit Source Code
  235.  
  236.  
  237.   *  Parse wParam and lParam immediately in WndProc routines.
  238.  
  239.   *  NULL is a valid return value from GetFocus and
  240.      GetActiveWindow.
  241.  
  242.   *  Use FindWindow instead of hPrevInstance to find other
  243.      running instances.
  244.  
  245.   *  GlobalLock and malloc will not return 64K aligned pointers.
  246.  
  247.   *  Use Windows 3.x DIB functions to initialize color bitmaps.
  248.  
  249.   *  Do not use GetInstanceData;  replace with supported IPC
  250.      mechanism.
  251.  
  252.   *  Do not share GDI object handles (e.g. pens, bitmaps) between
  253.      processes.
  254.  
  255.   *   Compile warning level -W2 or higher (-W3 recommended).
  256.  
  257.   *            Create function prototypes for all functions.
  258.  
  259.   *        Review structure member alignment and data types.
  260.  
  261.   *  Remove hardcoded buffer sizes (for example, file names and
  262.      path names).
  263.  
  264.   *  Do not extract private copies of WINDOWS.H definitions.
  265.  
  266.   *      Use unique typdefs (HPEN, HWND, not HANDLE or int).
  267.  
  268.  
  269. 3.1 A Brief Look at Windows 32-Bit
  270.  
  271. If you start with Windows 3.x source code, creating a native
  272. Windows 32-Bit application using the Windows 32-Bit API is
  273. straightforward and requires minimal source changes.  In general,
  274. the Windows 32-Bit API simply involves widening parameters and
  275. return values to 32 bits. Over the course of a few months,
  276. Microsoft ported a range of Windows 3.x source code to Windows
  277. 32-Bit, including the complete Windows 3.0 and Beta 3.1 software
  278. development kit sample code and relatively complex Windows 3.1
  279. applets--Program Manager, File Manager, Cardfile, and so on.
  280. This porting effort has validated the design of the Windows 32-
  281. Bit API and proven that it is possible to quickly create Windows
  282. 32-Bit applications from Windows 3.x sources.  As an additional
  283. exercise, Microsoft modified the Windows software development kit
  284. and system applet source code to be portable, allowing Windows
  285. 3.1 and Windows 32-Bit binaries to be created from the same code
  286. base.
  287.  
  288. The Windows 3.1 system applets contain more than 100,000 lines of
  289. source code. File Manager in particular contains approximately
  290. 20,000 lines of code; yet within one day it was compiling as a
  291. native Windows 32-Bit application.  Within a week, the File
  292. Manager could execute and display directory listings.  Changes
  293. included recoding several assembler routines in C so that the
  294. sources can be compiled for both Intel and RISC processors.  Few
  295. changes to the original Windows 3.x C code were required, which
  296. is indicated by the short time needed to create a functional,
  297. portable version of the File Manager.
  298.  
  299. An important porting factor is that Windows 3.x resource files
  300. containing menus, dialog boxes, icons, accelerator tables, and so
  301. on are directly compatible with the 32-bit Resource Compiler.
  302. You need not modify the resource files  for Windows 32-Bit.  This
  303. is not surprising, since the resource file is simply a script
  304. with no information that is 32-Bit sensitive.
  305.  
  306. 3.2 Windows 32-Bit Sample Source Code
  307.  
  308. The code fragment below is from the Windows 3.0 software
  309. development kit sample, GENERIC.  This code fragment compiles
  310. without modification  with either Windows 3.x or Windows 32-Bit
  311. development tools. Only one minor change to the entire GENERIC
  312. sample is required; the fragment builds completely as either a
  313. Windows 3.x or Windows 32-Bit binary.  Although the GENERIC
  314. sample is not particularly sophisticated, it does contain a menu
  315. and a dialog box, indicating that complex Windows functionality
  316. is easily supported.
  317.  
  318. If we look at the code fragment through the eyes of Windows 32-
  319. Bit, we see a true 32-bit application.  Function parameters,
  320. pointers, and structure members all widened from 16 to 32 bits.
  321.  
  322. This widening is accomplished "under the covers" by means of
  323. typedefs in WINDOWS.H (Windows 32-Bit version).  For example, the
  324. typedef LPSTR is a linear 32-bit pointer.  The variable hInst is
  325. defined as a 32-bit HANDLE.  The window handle, hWnd,  returned
  326. by CreateWindow, is a 32-bit window handle.  The window class
  327. structure contains 32-bit handles to icons, 32-bit linear
  328. pointers to string constants, and a 32-bit stock brush handle.
  329.  
  330.  
  331. Generic Sample Application from Windows 3.0 SDK
  332.  
  333. #include "windows.h"       /* required for all Windows applications*/
  334. #include "generic.h"       /* specific to this program    */
  335.  
  336. HANDLE hInst;              /* current instance    */
  337.  
  338. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  339. HANDLE hInstance;          /* current instance     */
  340. HANDLE hPrevInstance;      /* previous instance    */
  341. LPSTR lpCmdLine;           /* command line    */
  342. int nCmdShow;
  343. /* show-window type (open/icon) */
  344. {
  345.     MSG msg;
  346. /* message     */
  347.  
  348.     if (!hPrevInstance)  /* Other instances of app running? */
  349. if (!InitApplication(hInstance))/* Initialize shared things */
  350.     return (FALSE);      /* Exits if unable to initialize     */
  351.  
  352.     /* Perform initializations that apply to a specific instance*/
  353.  
  354.     if (!InitInstance(hInstance, nCmdShow))
  355.         return (FALSE);
  356.  
  357.     /* Acquire and dispatch messages until a WM_QUIT message is received. */
  358.  
  359.     while (GetMessage(&msg,                       /* message structure    */
  360.     NULL,                 /* handle of window receivieng thssage*/
  361.     NULL,                 /* lowest message to examine     */
  362.     NULL))                /* highest message to examine     */
  363. {
  364. TranslateMessage(&msg);   /* Translates virtual key codes    */
  365. DispatchMessage(&msg);    /* Dispatches message to window    */
  366.     }
  367.     return (msg.wParam);  /* Returns the value from PostQuitMessage */
  368. }
  369.  
  370. BOOL InitApplication(hInstance)
  371. HANDLE hInstance;        /* current instance     */
  372. {
  373.     WNDCLASS  wc;
  374.  
  375.  
  376.  /* Fill in window class structure with parameters that describe the  */
  377.     /* main window.       */
  378.  
  379.     wc.style = NULL;                    /* Class style(s).    */
  380.     wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for  */
  381.                                         /* windows of this class.             */
  382.     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
  383.     wc.cbWndExtra = 0;                  /* No per- window extra data.         */
  384.     wc.hInstance = hInstance;           /* Application that owns the class.   */
  385.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  386.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  387.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  388.     wc.lpszMenuName =  "GenericMenu";   /* Name of menu resource in .RC file. */
  389.     wc.lpszClassName = "GenericWClass"; /* Name used in call to CreateWindow. */
  390.  
  391.     /* Register the window class and return success/failure code.*/
  392.     return (RegisterClass(&wc));
  393. }
  394.  
  395. BOOL InitInstance(hInstance, nCmdShow)
  396.     HANDLE          hInstance;          /* Current instance identifier.       */
  397.     int             nCmdShow;           /* Param for first ShowWindow() call. */
  398. {
  399.     HWND            hWnd;               /* Main window handle.      */
  400.  
  401.     /* Save the instance handle in static variable, which will be used in  */
  402.     /* many subsequence calls from this application to Windows. */
  403.  
  404.     hInst = hInstance;
  405.  
  406.     /* Create a main window for this application instance.  */
  407.     hWnd = CreateWindow(
  408.         "GenericWClass",                /* See RegisterClass() call.          */
  409.         "Generic Sample Application",   /* Text for window title bar.         */
  410.         WS_OVERLAPPEDWINDOW,            /* Window style. */
  411.  
  412.  
  413.         CW_USEDEFAULT,                 /* Default hoorizontal position.      */
  414.         CW_USEDEFAULT,                 /* Default vertical position.         */
  415.         CW_USEDEFAULT,                 /* Default width.                     */
  416.         CW_USEDEFAULT,                 /* Default height.                    */
  417.         NULL,                          /* Overlapped windows have no parent. */
  418.         NULL,                          /* Use the window class menu.         */
  419.         hInstance,                     /* This instance owns this window.    */
  420.         NULL                           /* Pointer not needed.                */
  421.     );
  422.  
  423.     /* If window could not be created, return "failure" */
  424.     if (!hWnd)
  425.         return (FALSE);
  426.  
  427.     /* Make the window visible; update its client area; and return "success" */
  428.     ShowWindow(hWnd, nCmdShow);     /* Show the window                        */
  429.     UpdateWindow(hWnd);             /* Sends WM_PAINT message                 */
  430.     return (TRUE);                  /* Returns the value from PostQuitMessage */
  431. }
  432.  
  433.  
  434. 3.3 User Interface Code
  435.  
  436.  
  437. 3.3.1 Message Parameter Packing
  438. With the widening of handles to 32 bits, both wParam and lParam
  439. (the additional message parameters) must be 32 bits wide.  The
  440. impact is to wParam because lParam is already 32 bits wide in
  441. Windows 3.x.  If in Windows 3.x applications a handle and another
  442. value were packed into the high and low 16 bits of  lParam,
  443. widening to 32 bits requires repacking some values. A 32-bit
  444. handle occupies lParam completely, requiring the previously
  445. packed second parameter to be moved to wParam.  A few messages
  446. have been affected by handle widening, including WM_COMMAND,
  447. which is illustrated below:
  448.  
  449.      WM_COMMAND
  450.  
  451.           Win 3.x:    wParam == window id
  452.                       lParam == hwnd, command
  453.  
  454.           Win 32-Bit: wParam == window id, command
  455.                       lParam == hwnd
  456.  
  457. The WM_COMMAND window id and command parameters remain 16 bit
  458. values in Windows 32-Bit and can therefore be packed in the
  459. widened 32-bit wParam.  The 32-bit hwnd value is now fully
  460. contained in lParam.  To minimize the affect of parameter packing
  461. differences, a set of macros has been created that parse message
  462. parameters.  In this way, you can compile source code either as a
  463. Windows 3.x application  or as a Windows 32-Bit application
  464. without unique message handling code or C compiler #ifdef
  465. directives.  These macros will be in the Windows 32-Bit software
  466. development kit.  Examples of macros used to parse WM_COMMAND
  467. information are:
  468.  
  469.  
  470.      GET_WM_COMMAND_ID  (wParam, lParam) // Parse control ID value
  471.      GET_WM_COMMAND_HWND(wParam, lParam) // Parse control HWND
  472.      GET_WM_COMMAND_CMD (wParam, lParam) // Parse notification command
  473.  
  474. The underlying macro definitions are Windows 3.x and Windows 32-
  475. Bit specific; parsing the information from wParam or lParam as
  476. appropriate for each implementation.  The imporant point is that
  477. you can easily create readable source code that can be compiled
  478. for Windows 3.x or Windows 32-Bit.
  479.  
  480. 3.3.2 Parsing wParam/lParam
  481.  
  482. Because of the parameter repacking of several Windows messages,
  483. parse (extract) values from wParam and lParam in the message
  484. handling window procedure rather than passing parameters to
  485. worker functions where extraction occurs. If only wParam or
  486. lParam is passed to the worker routine, under Windows 32-Bit
  487. either parameter may no longer contain the value required by the
  488. worker routine.  Delayed extraction of message parameter data in
  489. worker routines is not always easy to spot.  Extracting the value
  490. within the message handling procedure localizes the impact of
  491. Windows 32-Bit message repacking.
  492.  
  493. An alternative solution is to always pass both wParam and lParam
  494. to worker routines.  In this way, the routine will always have
  495. access to parameter values, whether compiled for Windows 3.x or
  496. Windows 32-Bit.  This solution is less efficient because unused
  497. data is being transferred on the stack.
  498.  
  499. 3.3.3 Profile String Usage
  500. Systems offering Windows 32-Bit support will also provide a
  501. registration database.  All system and application configuration
  502. data will be stored in the database on a per user basis with
  503. appropriate security controls to assure that applications cannot
  504. corrupt one another's data or the system's configuration data. A
  505. centralized database has a number of advantages, including
  506. simpler installation, remote administration of workstation
  507. software, remote software updating, and error logging.
  508.  
  509. Windows 32-Bit versions of the Windows 3.x profile API (for
  510. example, GetProfileString, WriteProfileString) route profile
  511. string requests, including private profiles (that is, *.INI
  512. files) to the registration database transparently. Therefore, do
  513. not attempt to manipulate *.INI files directly with file I/O
  514. functions. These files will not exist, and the data contained in
  515. them is not accessible via file I/O calls; only the profile
  516. string API will be supported.
  517.  
  518. 3.3.4 Localized Input
  519.  
  520. The Windows 32-bit model is different from Windows 3.x in that
  521. input ownership is assigned at user input time -- when the input
  522. is created -- instead of when the input is read out of the system
  523. queue.  For this reason, each thread has its own input-
  524. synchronized state information.  In other words, each thread has
  525. its own input-synchronized picture of the mouse capture and the
  526. active window and is aware of which window has the focus.
  527. This change adds tremendous benefit to programmers and users
  528. alike.  It is no longer possible for an application that fails to
  529. process messages to bottleneck the system.  Unlike Windows 3.x
  530. and OS/2 Presentation Manager, no applications will be affected
  531. by other applications that process their messages slowly or who
  532. otherwise fail to check their message queue.
  533.  
  534. The following APIs are affected by localized input state:
  535.  
  536.      SetFocus( HWND )
  537.      GetFocus( VOID )
  538.      SetActiveWindow( HWND )
  539.      GetActiveWindow( VOID )
  540.      GetCapture( VOID )
  541.      SetCapture( HWND )
  542.      ReleaseCapture( VOID )
  543.  
  544. In general, the Get  APIs query only local current thread state.
  545. The Set APIs set state local to the window creator thread.  If
  546. the current thread did not create the window, then the current
  547. thread's related input state is set to NULL as if the input
  548. related state were being transferred between threads.
  549.  
  550. Thus, the Windows 3.x semantics of APIs that return input-
  551. synchronized state are changed slightly.  For example, SetFocus
  552. can be called with an hwnd and return TRUE for success, but a
  553. follow-up call to GetFocus might return NULL.  More
  554. substantially, GetFocus now returns NULL if the calling thread
  555. does not have a focus window. Under Windows 3.x,  GetFocus never
  556. returns NULL because a window in the system always has the
  557. keyboard focus.
  558.  
  559. Therefore, code applications to expect that functions such as
  560. GetFocus can return NULL as a legal value.  The return value
  561. should be tested against NULL before being used in subsequent
  562. function calls.
  563.  
  564. Mouse capture is affected in an added dimension.  The Windows 32-
  565. Bit server input thread cannot know ahead of time when an input
  566. thread will set the capture.  Also, regardless of the input state
  567. of any application, the system must allow the user direct input
  568. to any other application at any time.  Therefore, the semantics
  569. of mouse capture change slightly.
  570.  
  571. The semantics of how and when the capture changes are not
  572. affected; how and when an application gets mouse input is
  573. affected.  The Windows 32-Bit server will send all mouse input
  574. between a mouse down operation and a mouse up operation to the
  575. queue of the thread that created the window into which the
  576. original mouse down went.  Thus, the input thread processes mouse
  577. capture as the input is read out of the queue.  If the mouse
  578. button is down during the mouse capture, the capture window sees
  579. all input generated by the mouse, no matter where the mouse is on
  580. the screen, until the mouse button goes up or the mouse capture
  581. is released.  If a thread sets the mouse capture while the mouse
  582. button is up, the mouse capture window sees mouse events only as
  583. long as the mouse is over a window that thread created.
  584.  
  585.  
  586. 3.4 Graphics Interface Code
  587.  
  588.  
  589. 3.4.1 DIBs vs DDBs
  590. Beginning with Windows 3.0, device independent bitmaps (DIBs)
  591. have been the recommended format for creating and initializing
  592. bitmap data.  This format includes a header with bitmap
  593. dimensions, color resolution, and palette information supporting
  594. portability between Windows 3.x and Windows 32-Bit. Device
  595. dependent bitmaps (DDBs), as originally offered in Windows 1.x
  596. and 2.x, are not recommended.
  597.  
  598. Because DDBs lack complete header information, applications that
  599. directly manipulate DDB data are not portable to Windows 32-Bit.
  600. Developers are encouraged to write to the Windows 3.x DIB API
  601. (for example, SetDIBitmapBits); these calls are portable.
  602. Windows 32-Bit does provides, however, a subset of functionality
  603. for DDB API, such as SetBitmapBits:
  604.  
  605.   *  Monochrome DDBs are fully supported
  606.  
  607.   *  Caching color bitmaps with GetBitmapBits and SetBitmapBits
  608.      is supported
  609.  
  610. Caching implies that GetBitmapBits is used to save bitmap data on
  611. disk.  Under low memory situations in Windows versions 1.x and
  612. 2.x, the bitmap could be destroyed and easily restored with
  613. GetBitmapBits.  This implies that the DDB data is never
  614. manipulated; it is simply backed up and restored on disk in its
  615. original form.  While caching is not needed in Windows 32-Bit,
  616. source code employing this technique will still be supported.
  617.  
  618. Windows 32-Bit does not support initializing color DDBs with
  619. CreateBitmap. Such code is also not portable among Windows 3.x
  620. systems with different display drivers because DDB data is device
  621. driver dependent.
  622.  
  623.  
  624. 3.4.2 Sharing Graphical Objects
  625.  
  626. Windows 3.x runs all Windows applications in a shared address
  627. space.  Data can be directly manipulated, and other Windows
  628. processes can directly access per-process objects that the system
  629. created. This architecture has been exploited by some
  630. applications that create a single graphical object, such as a pen
  631. or a bitmap, and allow separate processes to use the pen or draw
  632. on the bitmap.
  633.  
  634. Windows 32-Bit applications run in separate address spaces, and
  635. graphical objects are owned by the process that creates them.
  636. Only its owner can manipulate a graphical object.  A handle to a
  637. bitmap passed to another process cannot be used by that process
  638. because the original process retains ownership of the bitmap.
  639.  
  640. Pens and brushes should be created by each process.  A
  641. cooperative process may access the bitmap data in shared memory
  642. (via standard interprocess communications) and create its own
  643. copy of the bitmap.  Alterations to the bitmap must be
  644. communicated between the cooperative processes via interprocess
  645. communication and a proper protocol.  One such protocol is DDE.
  646. Windows 32-Bit will add an explicit ownership transfer API for
  647. graphical objects to explicitly allow cooperative applications to
  648. share graphical objects.
  649.  
  650. 3.5 Base System Support
  651.  
  652.  
  653. 3.5.1 Instance Initialization
  654.  
  655. The first release of Windows (version 1.01) was designed to run
  656. in 8088-based systems, which assumed limited installed memory
  657. (512K RAM).  Functions such as GetInstanceData and knowledge
  658. about other instances of an application already running allowed
  659. efficient data sharing and initialization using data belonging to
  660. other running instances. On secure systems in which applications
  661. run in separate address spaces, these functions no longer are
  662. appropriate.
  663.  
  664. Therefore, applications that want to share data among several
  665. instances must replace calls to GetInstanceData with standard
  666. interprocess communication techniques such as shared memory
  667. and/or DDE.
  668.  
  669. A Windows 32-Bit version of WinMain supports the same parameter
  670. list as does Windows 3.x:
  671.  
  672.      int WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  673.  
  674. However, the parameter hPrevInstance always returns NULL,
  675. indicating that this is the first instance of the application,
  676. regardless of any other already-running instances. Although this
  677. situation would appear to be a problem, the initialization of
  678. most applications is handled correctly.  Under Windows 3.x,
  679. multiple instances can share private window classes registered by
  680. the first instance.  Under Windows 32-Bit, each instance is
  681. required to register it own window classes.
  682.  
  683. Applications usually test hPrevInstance to see if they must
  684. register their window class.  This test is guaranteed to work
  685. optimally under Windows 32-Bit, always indicating the first
  686. instance of the application, and Windows 32-Bit requires that
  687. every instance register its own window classes.
  688.  
  689. Some applications, however, must know if other instances are
  690. running.  Sometimes data sharing is required, but typically
  691. applications that care about multiple instances are interested in
  692. assuring that only one instance of the application runs at any
  693. time.  An example is the Control Panel; another is the Task
  694. Manager.
  695.  
  696. Applications such as these cannot use hPrevInstance in Windows
  697. 32-Bit to test for previous instances. These applications must
  698. use an alternative method, such as creating a unique named pipe,
  699. broadcasting a unique message, or calling FindWindow.   If
  700. another instance is found, the application determines which
  701. instance should be terminated.
  702.  
  703.  
  704. 3.5.2 Memory Manipulation
  705.  
  706. Under the Windows 3.x segmented memory architecture, globally
  707. allocated memory always aligns on segment boundaries.  Both
  708. GlobalAlloc and the C runtime malloc family of functions allocate
  709. global memory in a way that the 16-bit offset of the 32-bit
  710. segmented pointer that references the base address of this data
  711. is always 0.
  712.  
  713. This behavior is not portable to linear memory.  Memory
  714. allocation is not guaranteed to  align on 64K boundaries.  Memory
  715. is allocated with a 4K page granularity, but some objects may be
  716. packed to fit within a single page to maximize memory efficiency.
  717. (See below for more information about pointer manipulation.)
  718.  
  719.  
  720. 3.5.3 Windows 32-Bit API Replacements for Int 21
  721.  
  722. Direct INT21 calls or the use of the Windows 3.x DOS3Call API to
  723. request MS-DOS to perform file I/O operations must  be replaced
  724. by the appropriate Windows 32-Bit file I/O calls.  Windows 32-Bit
  725. offers a complete set of named APIs to replace nonportable INT21
  726. calls including:
  727.  
  728.    INT 21H Function                   DOS Operation    Windows
  729.    32-Bit API Equivalent
  730.      0EH            Select Disk         SetCurrentDirectory
  731.      19H            Get Current Disk    GetCurrentDirectory
  732.      2AH            Get Date            GetDateAndTime
  733.      2BH            Set Date            SetDateAndTime
  734.      2CH            Get Time            GetDateAndTime
  735.      2DH            Set Time            SetDateAndTime
  736.      36H            Get Disk Free Space GetDiskFreeSpace
  737.      39H            Create Directory    CreateDirectory
  738.      3AH            Remove Directory    RemoveDirectory
  739.      3BH            Set Current Directory    SetCurrentDirectory
  740.      3CH            Create Handle       CreateFile
  741.      3DH            Open Handle         OpenFile
  742.      3EH            Close Handle        CloseHandle
  743.      3FH            Read Handle         ReadFile
  744.      40H            Write Handle        WriteFile
  745.      41H            Delete File         DeleteFile
  746.      42H            Move File Pointer   SetFilePointer
  747.      43H            Get File Attributes GetAttributesFile
  748.      43H            Set File Attributes SetAttributesFile
  749.      47H            Get Current Directory    GetCurrentDirectory
  750.      4EH            Find First File     FindFirstFile
  751.      4FH            Find Next File      FindNextFile
  752.      56H            Change Directory Entry   MoveFile
  753.      57H            Get Date/Time of File    GetDateAndTimeFile
  754.      57H            Set Date/Time of File    SetDataAndTimeFile
  755.      59H            Get Extended Error  GetLastError
  756.      5AH            Create Unique File  GetTempFileName
  757.      5BH            Create New File     CreateFile
  758.      5CH            Lock                LockFile
  759.      5CH            Unlock              UnlockFile
  760.      67H            Set Handle Count    SetHandleCount
  761.  
  762.  
  763. In most situations, the standard C runtime libraries are
  764. sufficient for normal file I/O.  The C runtime has the advantage
  765. of being portable across many platforms.
  766.  
  767.  
  768. 3.5.4 Dynamic Link Libraries
  769.  
  770. DLL initialization and termination functions behave differently
  771. in Windows 3.xand Windows 32-Bit in terms of how they are
  772. defined, when they are called, and the information that is made
  773. available to them.  Windows 32-Bit DLLs are easier to create and
  774. have functionality not currently available in Windows 3.x.  In
  775. Windows 3.x, initialization and termination functions must be
  776. provided: the termination function must be named WEP, and the
  777. initialization function is the DLL MASM entry point.
  778. Initialization and termination functions are optional in Windows
  779. 32-Bit DLLs.
  780.  
  781. In Windows 3.x, the DLL initialization function is called once,
  782. when the DLL is first loaded in the system.  The function is not
  783. called again, even if other applications that use the DLL are
  784. invoked.  Likewise, the DLL termination function is not called
  785. until the DLL is unloaded from the system, when the last
  786. application using it terminates or frees the library.  The
  787. initialization and termination functions are distinct.  The
  788. startup code for the initialization function must be in assembly
  789. language, to allow access to parameters that are passed in
  790. machine registers.
  791.  
  792. In Windows 32-Bit, the DLL initialization function is the same as
  793. the termination function, and its name is specified at link time.
  794. Initialization or termination functionality is selected by a
  795. Boolean parameter, bAttaching,  passed to the initialization
  796. function.  The DLL initialization function is called each time a
  797. process attaches to the DLL for the first time or detaches from
  798. the DLL for the last time.  Thus, if five processes access the
  799. same DLL, the DLL's initialization function is invoked five times
  800. with the bAttaching parameter set to TRUE.  When these five
  801. processes terminate, detaching the DLL from each process causes
  802. five calls to the DLL initialization function, with the
  803. bAttaching parameter set to FALSE.
  804.  
  805. Windows 3.x DLLs are typically implemented completely in assembly
  806. language or in C and linked to the standard LIBENTRY.ASM
  807. function.  This function calls LibMain after initializing the
  808. heap and saving appropriate registers.  In porting to Windows 32-
  809. Bit, DLLs implemented in assembly language should be rewritten in
  810. C so that they are portable to RISC-based systems.
  811.  
  812. Windows 3.x DLL initialization functions are passed the following
  813. information:
  814.  
  815.   *  the DLL's instance handle
  816.  
  817.   *  the DLL's data segment (DS)
  818.  
  819.   *  the heap size specified in the DLL's .DEF file
  820.  
  821.   *  the command line
  822.  
  823.  
  824. Windows 32-Bit DLL initialization functions are passed the
  825. following information:
  826.  
  827.   *  the DLL's module handle
  828.  
  829.   *  the bAttaching Boolean, selecting initialization or
  830.      termination
  831.  
  832. The Windows 32-Bit module handle is analogous to the Windows 3.x
  833. instance handle.  In Windows 32-Bit, the data segment is
  834. irrelevant because declared DLL data is either private to each
  835. process accessing the DLL or shared among cooperative processes
  836. accessing the DLL. The DLL's module definition file controls
  837. whether DLL data is shared or private. The heap size is not
  838. passed to the Windows 32-Bit DLL initialization function because
  839. all calls to local memory management functions operate on the
  840. default heap, which is provided to each process.  The command
  841. line does not need to be passed as a parameter since it can be
  842. obtained under Windows 32-Bit through an API function.
  843.  
  844. Although the Windows 3.x LIBENTRY.ASM routine contains
  845. nonportable assembly routines, it isolates the assembly language
  846. initialization and supports writing additional DLL-specific
  847. initialization in C via the LibMain routine.  For portability to
  848. Windows 32-Bit,  DLL initialization code should be added to the
  849. LibMain routine and written in C. (For further information on
  850. LIBENTRY.ASM, see the Windows 3.x software development kit
  851. documentation.).
  852.  
  853.  
  854. 3.6 C Coding Guidelines
  855.  
  856. The Windows 32-Bit API was designed to simplify the creation of
  857. Windows 32-Bit applications from Windows 3.x sources.  Specific
  858. API differences have been discussed above.  Creating portable
  859. Windows code also involves writing portable C.  Fortunately, the
  860. similarity of Windows 3.x and Windows 32-Bit requires only that a
  861. concise set of portable C guidelines be followed.  Windows
  862. programs have generally been optimized to operate with the
  863. segmented Intel architecture.  Therefore, the change from
  864. segmented to linear memory is the most significant issue in
  865. creating portable C code
  866.  
  867. 3.6.1 Pointer Manipulation
  868. Windows 32-Bit supports a compatible set of memory management
  869. functions, such as GlobalAlloc and GlobalLock, and a new set of
  870. advanced linear memory APIs.  Therefore, existing Windows
  871. applications can easily be converted to Windows 32-Bit and
  872. continue to use the Windows 3.x memory allocation and handle
  873. dereferencing API.
  874.  
  875. As mentioned previously, memory allocations are not aligned on
  876. 64K boundaries.  Therefore, any pointer arithmetic based on
  877. assumptions of segment:offset encoded pointers will fail in
  878. Windows 32-Bit.  When computing offsets to arrays of structures,
  879. do not create pointers by combining a computed 16-bit offset with
  880. the high-order 16 bits of an address pointer.  This type of
  881. pointer arithmetic depends on segment:offset encoded addresses.
  882.  
  883.  
  884. Several other pointer characteristics should be observed:
  885.  
  886.   *  All pointers (even pointers to objects in the local heap)
  887.      grow to 32 bits
  888.  
  889.   *  Code that takes advantage of 16-bit pointer address wrapping
  890.      is not appropriate with linear addresses
  891.  
  892.   *  Structures that hold NEAR pointers in Windows 3.x will grow
  893.      from 2 bytes to 4 bytes in Windows 32-Bit
  894.  
  895.  
  896. 3.6.2 Promotions and Ranges
  897.  
  898. Expressions involving the C integer data types (int and unsigned
  899. int) should be reviewed for portability, especially if the
  900. compiler already generates warnings about signed/unsigned
  901. mismatches or conversion warnings.  The int data-type grows from
  902. 16 to 32 bits, which can subtly affect applications compiled for
  903. Windows 32-Bit.  Typical problems encountered are sign extensions
  904. and assumptions (sometimes unintentional) about ranges. Loops
  905. that take advantage of 16-bit ints and of the fact that integer
  906. loop counters will wrap at 32767 or 65535 will experience
  907. problems when the integer loop counters grow to 32-bit and
  908. wrapping occurs at 2GB or 4GB.
  909.  
  910. 3.6.3 Structure Member Alignment
  911. Data accesses to unnaturally aligned data elements are expensive
  912. on some hardware architectures and are illegal on others.  For
  913. example, on the Intel 80386 accessing a DWORD that is not 4-byte
  914. aligned results in a performance penalty.  When the same code is
  915. moved to a MIPS RISC processor, the misaligned access generates a
  916. fault.  The system handles the fault, and system software decodes
  917. the data. Although the code is portable, it is not efficient.
  918. Therefore,  all data elements should be aligned consistently with
  919. their type.  Alignment rules vary with architecture, but the
  920. following guidelines are appropriate for the Intel and MIPS
  921. processors targeted by Windows 32-Bit:
  922.  
  923.      Windows 32-Bit Structure Member Alignment
  924.  
  925.           char:          Align on byte boundaries
  926.  
  927.           short (16-bit):      Align on even byte boundaries
  928.  
  929.           int/long (32-bit):      Align on 32-bit boundaries
  930.  
  931.           float/double:  Align on 32-bit boundaries
  932.  
  933.           structures:    Align on 32-bit boundaries
  934.  
  935. Creating a portable structure that is both efficient in memory
  936. usage (without packing) and aligned properly is possible.
  937.  
  938.  
  939.  
  940. 3.6.4 Unique Typedefs
  941.  
  942. As illustrated in the GENERIC code fragment listed earlier in
  943. this document, unique typedefs are useful in creating portable
  944. code. Even though the typedefs can have different underlying
  945. definitions in Windows 3.x and Windows 32-bit,  Windows source
  946. code can remain unchanged.
  947.  
  948. Windows offers unique typedefs for most objects defined in
  949. WINDOWS.H.  Unique typedefs such as HPEN, HBRUSH, and HWND better
  950. support portability to Windows 32-Bit than generic typedefs such
  951. as HANDLE.  Although all handles in Windows 3.x are
  952. interchangeable with HANDLE or unsigned int, using these basic
  953. data types affects porting to Windows 32-Bit because various
  954. objects require different typedefs under Windows 32-Bit than
  955. under Windows 3.x.
  956.  
  957. Just as using unique typedefs is recommended when defining (or
  958. casting) Windows objects, creating a complete set of unique
  959. typedefs for application-specific objects is also strongly
  960. recommended.  As with the Windows objects, the underlying
  961. application-specific data types and structures can be modified
  962. and minimally affect source code that uses these data types.
  963.  
  964. 3.6.5 General Recommendations
  965.  
  966. The following coding recommendations are well known but are
  967. occasionally ignored.  Reviewing your code and addressing the
  968. following issues will create more robust Windows 3.1 code and
  969. will create code that is more easily ported to Windows 32-Bit.
  970.  
  971. Review hard-coded buffer sizes for file names and environment
  972. strings. Although dynamically allocating buffers to hold strings
  973. is not necessary, Windows 32-Bit supports long file names (256
  974. characters).  Therefore, buffers hard coded assuming FAT 8.3
  975. format will not take advantage of long file name support.  Using
  976. a #define to define sizes for array allocations will assist
  977. portability of the source code to Windows 32-Bit.  Windows 32-Bit
  978. will add support for "opaque" file names, which will offload
  979. details of creating and parsing pathnames from the application to
  980. the operating system.  Among the benefits is transparant support
  981. for accessing files on new file systems such as mini or mainframe
  982. servers sharing named resources on a network.  The application is
  983. freed from knowing the file formats and network naming
  984. conventions when interacting with other PCs, VAX systems, or
  985. other "foreign" file systems.  Removing hard-coded buffer sizes
  986. is the first step in taking advantage of opaque file naming.
  987.  
  988. Compile all sources at warning level 2 (-W2), warning level 3 (-
  989. W3) is recommended.  Warning level 3 has been a problem in the
  990. past because WINDOWS.H included non-ANSI C compliant bitfield
  991. definitions that did not pass at this level.  The latest release
  992. of the Microsoft C compiler (C 6.00a) moves this fatal error to
  993. -W4, allowing the strict type checking of -W3.
  994.  
  995. Create function prototypes for all functions.  Relying on default
  996. C compiler handling is often (but not guaranteed to be) portable.
  997. In addition to parameter assumptions, the Microsoft C compiler
  998. supports various calling conventions (_cdecl, _pascal, and so
  999. on), and the default calling convention may change because of
  1000. future ANSI C requirements.  Using function prototypes helps
  1001. isolate source code from default compiler behavior and changes in
  1002. the ANSI C definition.
  1003.  
  1004. Until recently, the size of WINDOWS.H has been a problem for the
  1005. Microsoft C compiler, causing out of heap space problems in Pass
  1006. 1 and/or Pass 2 of the compiler.  This problem is corrected in
  1007. the MS-DOS extender version of the MS C compiler (C 6.00ax).
  1008. ISVs have worked around this previous limitation by extracting
  1009. specific WINDOWS.H definitions into their source code.  This
  1010. could cause portability problems if these WINDOWS.H definitions
  1011. are not updated with Windows 32-Bit definitions when the source
  1012. is compiled under Windows 32-Bit.  Therefore, either remove
  1013. extracted header information and rely on WINDOWS.H, or clearly
  1014. highlight extracted information for modification when building a
  1015. Windows 32-Bit version.
  1016.  
  1017.  
  1018. 4. Summary of Compatibility Rules
  1019.  
  1020.  
  1021. Rules for Windows 3.x Binary Compatibility on Windows NT
  1022.   *  Ensure that Windows 3.x applications run in
  1023.      Standard/Enhanced mode.
  1024.  
  1025.   *  Use published Windows 3.x APIs, messages, and structures.
  1026.  
  1027.   *  Do not modify WIN.INI directly; use a profile string API.
  1028.  
  1029.   *  Restrict direct port I/O (only standard devices).
  1030.  
  1031.   *  Do not directly access the disk controller; doing so is a
  1032.      security violation.
  1033.  
  1034.   *  Do not modify the system date and time; doing so is a
  1035.      security violation.
  1036.  
  1037. Rules for Portable Windows 3.x/Windows 32-Bit Source Code
  1038.  
  1039.   *  Parse wParam and lParam immediately in WndProc routines.
  1040.  
  1041.   *  NULL is a valid return value from GetFocus and
  1042.      GetActiveWindow.
  1043.  
  1044.   *  Use FindWindow instead of hPrevInstance to find other
  1045.      running instances.
  1046.  
  1047.   *  GlobalLock and malloc will not return 64K aligned pointers.
  1048.  
  1049.   *  Use Windows 3.x DIB functions to initialize color bitmaps.
  1050.  
  1051.   *  Do not use GetInstanceData;  replace with supported IPC
  1052.      mechanism.
  1053.  
  1054.   *  Do not share GDI object handles (e.g. pens, bitmaps) between
  1055.      processes.
  1056.  
  1057.   *   Compile warning level -W2 or higher (-W3 recommended).
  1058.  
  1059.   *            Create function prototypes for all functions.
  1060.  
  1061.   *        Review structure member alignment and data types.
  1062.  
  1063.   *  Remove hardcoded buffer sizes (for example, file names and
  1064.      path names).
  1065.  
  1066.   *  Do not extract private copies of WINDOWS.H definitions.
  1067.  
  1068.   *      Use unique typdefs (HPEN, HWND, not HANDLE or int).
  1069.  
  1070.