Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
16 KiB

  1. Header File Organization
  2. ------------------------
  3. This document describes the rules for public Windows 3.1 header files. These
  4. rules are designed to promote consistency, clarity, Win32 compatibility, ANSI
  5. compatibility, motherhood, and apple pie a la mode.
  6. In the past, windows.h has been fairly randomly organized: it wasn't very
  7. easy to look in the file and figure out how constants, types, and functions
  8. are related. However, the new windows.h is much more rationally organized,
  9. and it's now far easier to understand and modify. In interests of
  10. consistency, readability, and maintainability, it's important that all of our
  11. public header files are consistently organized.
  12. * Include a copyright banner at the top of the file. Something like:
  13. /*****************************************************************************\
  14. * *
  15. * header.h - Brief description of purpose of header file *
  16. * *
  17. * Version 3.10 * *
  18. * *
  19. * Copyright (c) 1992, Microsoft Corp. All rights reserved. *
  20. * *
  21. \*****************************************************************************/
  22. If this header file has been released before, the copyright date
  23. should be something like: 1985-1992.
  24. * Arrange your header in functional groups, like windows.h. Try to
  25. keep related types, structures, constants and functions as close
  26. together as possible in the header. Separate functional groups
  27. within the header with a banner comment, as in windows.h.
  28. * Within a functional group, general typedefs and constants should come
  29. first, followed by logically organized function prototypes.
  30. * Constants or types used by only one or two functions should be
  31. declared near the function.
  32. * Make sure that everything defined in the header file is included by
  33. default: don't require people to #define things to get certain
  34. definitions.
  35. * If you do want to break up your header file, use the #define NOXXX
  36. convention used by windows.h. Try not to have too many groups
  37. controled by NOXXX #defines, because they get confusing and hard to
  38. deal with. Compiler speed and memory capacity is not the problem it
  39. once was, especially with precompiled headers.
  40. * Constants designed to be ANDed or ORed should be defined in hex.
  41. The number of digits should reflect the data size: 2 for bytes,
  42. 4 for words, and 8 for longs. Long hex constants should have
  43. an appended L, e.g., 0x12345678L.
  44. * Ordinal constants values (e.g., 1, 2, 3, 4) should be declared
  45. in decimal.
  46. * Provide a comment on all #else's and #endif's that suggests its
  47. corresponding #ifdef: e.g.
  48. #ifdef FOO
  49. ...
  50. #else /* FOO */
  51. #endif /* !FOO */
  52. * Precede the header file with #pragma pack(1), and terminate with
  53. #pragma pack(). This ensures that the structures declared in the
  54. header will be packed properly, regardless of what compiler packing
  55. options the user is using for his own code. Because the Windows RC
  56. compiler chokes on #pragma statements in .rc files, it's a good idea
  57. to include this (and any other #pragmas) in an #ifndef RC_INVOKED.
  58. #ifndef RC_INVOKED
  59. #pragma pack(1) /* Assume byte packing throughout */
  60. #endif /* RC_INVOKED */
  61. and:
  62. #ifndef RC_INVOKED
  63. #pragma pack() /* Revert to default packing */
  64. #endif /* RC_INVOKED */
  65. * Prevent multiple inclusion of your header file with the following
  66. construct:
  67. #ifndef _INC_MYHEADER
  68. #define _INC_MYHEADER
  69. ...body of header...
  70. #endif /* _INC_MYHEADER */
  71. This is the convention used by the C runtimes. For each header there
  72. is a #define that can be used to determine whether the header has
  73. already been included.
  74. Win32 Upward Compatibility
  75. --------------------------
  76. Part of the goal of 3.1 is to provide a more unified API that will scale with
  77. minimal pain to 32 bits in Win32. To this end, there are a few things you
  78. have to worry about in your headers (and in your code, but that's a different
  79. story...)
  80. In 32-bit Windows, almost all 16 bit parameters, return values, and field
  81. types have been widened to 32 bits. This allows us to generate much more
  82. efficient code on the 386 and on RISC machines.
  83. We need a way of declaring the quantities that will "float" to 32 bits in
  84. 32-bit Windows. It turns out that the C language already provides for this
  85. capability: the "int" type, for example, is 16 bits on 16 bit platforms, but
  86. is 32 bits on 32 bit platforms. "short" is always 16 bits on any platform,
  87. "long" is always 32 bits, and "char" is always 8 bits.
  88. So, functions and structures with "int" declarations are already portably
  89. declared. The problem, though is with the WORD type. "WORD" has become an
  90. industry-wide synonym for a 16 bit unsigned quantity. But, it's also used
  91. widely in Windows header files.
  92. Enter the UINT type. The new UINT type is typedef'd as "unsigned int": an
  93. unsigned value that is 16 bits on 16 bit platforms, and floats to 32 bits on
  94. 32 bit platforms. In the 3.1 headers, UINT is used in place of WORD wherever
  95. the size of the return value, parameter, or field will change depending on
  96. the platform.
  97. This is a rule that applies to code you write too: on 32 bit platforms, use
  98. of the UINT type rather than WORD will generate faster smaller code. But be
  99. careful of hard-coded size dependencies on WORD: be sure to use sizeof()
  100. instead of constants, etc.
  101. In some cases there may be structure fields whose size WON'T be changing in
  102. 32-bit windows, perhaps because the structure is used in a file format and
  103. compatibility is required. If you know ahead of time that this is the case,
  104. be sure to use short and WORD to indicate 16 bit quantities across platforms.
  105. There are a few of these exceptions with the 3.1 bitmap information
  106. structures in windows.h. If you don't know, then use UINT and int.
  107. The new WPARAM, LPARAM, and LRESULT types, used for polymorphic or arbitrary
  108. parameters and return values (e.g., the SendMessage() function), also provide
  109. a useful degree of platform isolation. The WPARAM type is similar to UINT in
  110. that its size varies with the platform. WPARAM should be used in function
  111. parameter, return value, AND structure declarations, even though its size may
  112. vary. The use of these types indicates to the programmer that the value must
  113. be cast and assigned to the proper type before use.
  114. Hence, the following rules:
  115. * Use int and UINT instead of short or WORD, UNLESS you know for sure
  116. that the quantity will remain 16 bits in 32-bit Windows. The Windows
  117. HIWORD and LOWORD macros use WORD, for example. Be sure to check your
  118. uses of short as well as WORD: there are probably a few lurking out
  119. there that should be changed to int. Use int FAR* or UINT FAR* instead
  120. of LPINT or LPWORD.
  121. * Use the LPARAM, WPARAM, and LRESULT types instead of WORD, LONG, or
  122. DWORD as appropriate.
  123. ANSI Compatibility
  124. ------------------
  125. Public header files should be ANSI compliant so that people can take
  126. advantage of the highest compiler warning levels possible. This also helps
  127. ensure that our header files work with a wider range of development tools.
  128. * Don't define constants, typedefs, or functions named with a preceding
  129. underscore. This violates the ANSI namespace conventions. There are
  130. a few violations of this rule already in existence (e.g., _lread), but
  131. try not to create any new problems. (The rules are actually more
  132. complicated than "don't use underscores", but you're safe if you keep
  133. away from them).
  134. * Don't use "//" style comments in the header: these are convenient
  135. but non-ANSI, and warning level 4 complains.
  136. * Always test your header file by compiling it with the -W4 compiler
  137. option to ensure that it's ANSI-compatible.
  138. * Make sure that you have no identifier conflicts with the following
  139. C library header files (NOTE: This list may be incomplete. It's
  140. a good start, though).
  141. assert.h
  142. ctype.h
  143. errno.h
  144. float.h
  145. limits.h
  146. locale.h
  147. math.h
  148. setjmp.h
  149. signal.h
  150. stdarg.h
  151. stddef.h
  152. stdio.h
  153. stdlib.h
  154. string.h
  155. time.h
  156. * Structure declarations should be declared with the "tag" prefix, rather
  157. than a leading underscore, as shown below:
  158. typedef struct tagFOO
  159. {
  160. int i;
  161. UINT u;
  162. } FOO;
  163. * Declare fully-prototyped typedefs for all callback functions. By
  164. convention, the type name should be all caps and end in PROC. For
  165. example, the window procedure callback function typedef from windows.h:
  166. typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
  167. Windows 3.0 Backward Compatibility
  168. ----------------------------------
  169. In order to allow users to develop applications with 3.1 headers that will
  170. still run on 3.0, users can #define the WINVER constant to be equal to the
  171. version number of Windows they are compiling against. For 3.0, this would be
  172. 0x0300. This constant should be used to ensure that new, non-3.0 compatible
  173. features are not declared when the user is compiling a 3.0 application. Keep
  174. in mind that this version number is hex, not decimal (to be compatible with
  175. the GetExpWinVer() API).
  176. Some of you may own headers that are designed to work with windows 3.0 as
  177. well as 3.1: in this case, you won't have some of the new 3.1 typedefs and
  178. macros defined (e.g., UINT). You can use #ifdef _INC_WINDOWS to determine
  179. whether you've included the 3.1 windows.h. Because yours may not be the only
  180. header that will want to define certain types like UINT and LPCSTR, you
  181. should #define these to be WORD and LPSTR, respectively, since you cannot
  182. typedef something twice. The other option, of course, is to have separate
  183. 3.0 and 3.1 versions of your header.
  184. * New, non-3.0 compatible declarations and definitions should be inside
  185. #ifdef (WINVER >= 0x030a)/#endif so that the 3.1 headers can be used
  186. to create 3.0-compatible applications.
  187. * If your header must be compatible with the 3.0 windows.h, use #ifdef
  188. _INC_WINDOWS around #definitions that define the missing types. The
  189. 3.0 windows.h file did not #define _INC_WINDOWS.
  190. Use #define rather than typedef to ensure that other headers can
  191. safely do the same thing. Here's an example that will handle
  192. most of the common problems:
  193. #ifndef _INC_WINDOWS /* If not included with 3.1 headers... */
  194. #define LPCSTR LPSTR
  195. #define WINAPI FAR PASCAL
  196. #define CALLBACK FAR PASCAL
  197. #define UINT WORD
  198. #define LPARAM LONG
  199. #define WPARAM WORD
  200. #define LRESULT LONG
  201. #define HMODULE HANDLE
  202. #define HINSTANCE HANDLE
  203. #define HLOCAL HANDLE
  204. #define HGLOBAL HANDLE
  205. #endif /* _INC_WINDOWS */
  206. C++ Compatibility
  207. -----------------
  208. To be able to use functions declared in your header directly from C++, you
  209. need to do one thing:
  210. * Bracket the header file typedefs inside an extern "c" {} block,
  211. conditionally using the __cplusplus #define:
  212. Near the beginning of your header:
  213. #ifdef __cplusplus
  214. extern "C" { /* Assume C declarations for C++ */
  215. #endif /* __cplusplus */
  216. And at the end:
  217. #ifdef __cplusplus
  218. }
  219. #endif
  220. STRICT Compatibility and Windows 3.0 Backward Compatibility
  221. -----------------------------------------------------------
  222. One of the most important features of STRICT is that handle types are no
  223. longer defined as WORDs. They are declared in such a way that will cause a
  224. compiler error if you try to pass the wrong type of handle or a non-handle
  225. value to a function, for example. It's important that all of our handle
  226. types be declared this way when the user #defines STRICT.
  227. A number of new types and such have been defined in windows.h, such as
  228. HINSTANCE, HGLOBAL, and HLOCAL, which should be used where appropriate in
  229. place of the generic HANDLE type. HANDLE should be used only in cases of
  230. an arbitrary handle type.
  231. The WPARAM, LPARAM, and LRESULT types should be used for arbitrary or
  232. polymorphic parameters or return values. Typedefs exist for all callback
  233. functions, which are used in place of FARPROC.
  234. In most cases, functions declared with these types are fully 3.0 compatible
  235. unless STRICT is #defined. It may sometimes be necessary to use #ifdef
  236. STRICT/#else/#endif to provide 3.0-compatible, non-STRICT declarations in
  237. some cases.
  238. * Use DECLARE_HANDLE() to declare handle types. If you have polymorphic
  239. API parameters (or structure fields) that are designed to accept more
  240. than one type of handle (e.g., the GDI SelectObject function), there
  241. are a few tricks you can employ. 1) Declare a generic handle type
  242. like HGDIOBJ as void _near*, which will accept any handle type. The
  243. HANDLE type can be used for this purpose. 2) if the number of
  244. polymorphic types is small, and there are lots of cases where they can
  245. be used polymorphically, use DECLARE_HANDLE to declare one handle
  246. type, and typedef the rest to be the same as the first one (e.g,
  247. HMODULE and HINSTANCE in windows.h).
  248. * Structure and function declarations should use the appropriate STRICT
  249. type, rather than the generic HANDLE,
  250. * Declare arbitrarily or polymorphic types with LPARAM, WPARAM, and
  251. LRESULT instead of WORD, LONG, or DWORD. This indicates to a
  252. programmer that these values should not be used directly, but should
  253. instead be cast and assigned to the proper type of value before use.
  254. * Declare arbitrarily or polymorphic pointer types with void FAR*
  255. instead of LPSTR or BYTE FAR*. The nice thing about the void FAR*
  256. type is that you can pass any type of pointer to it without having to
  257. cast first.
  258. * If any of the above STRICT rules result in declarations that are
  259. not compatible with previously released versions of the header file,
  260. use #ifdef STRICT/#else/#endif to ensure that both declarations
  261. are present.
  262. * Use WINAPI instead of FAR PASCAL for declaring APIs. Use CALLBACK
  263. instead of FAR PASCAL in callback function typedefs.
  264. * Be sure to use "const" where appropriate in your pointer parameters.
  265. If the pointer is read-only, then it should be const. If the function
  266. writes through the pointer, it must not be const. For const
  267. zero-terminated string pointers, use LPCSTR instead of LPSTR.
  268. * Don't declare NPXXX or SPXXX pointer parameter types for new structures.
  269. (but don't remove them if they've already been defined in a shipped
  270. header). Users are encouraged to use "*", const, _near, _far, and
  271. _huge explicitly where appropriate. Now that our headers contain
  272. "const" pointer types, having LP, NP, and const pointer type variants
  273. for every structure would just clog the compiler up with typedefs.
  274. * Spell out pointer declarations, rather than using the LPXXX type form.
  275. This allows for use of const and _huge where appropriate, without
  276. having to define lots of new typedefs:
  277. SetFoo(const FOO FAR* pfoo);
  278. GetFoo(FOO FAR* pfoo);
  279. * Use parameter names in your API function prototypes. This greatly
  280. contributes to the readability and usefulness of your header, at
  281. very little cost. Make sure all your APIs and callback declarations
  282. are fully prototyped. Use the same naming conventions as in our
  283. documentation (contact gregro or ralphw for a summary of those
  284. conventions). NOTE: As of this writing, windows.h does not yet
  285. include function prototype names.