How to Tame the Windows Headers (Useful Defines)

How to tame the Windows headers (useful defines)?

The most commonly used is probably WIN32_LEAN_AND_MEAN - it disables rarely used parts of the API. You can find more on MSDN's Using the Windows Headers.

I remembered wrong about MSDN listing those defines, so here's list from windows.h:

/*  If defined, the following flags inhibit definition
* of the indicated items.
*
* NOGDICAPMASKS - CC_*, LC_*, PC_*, CP_*, TC_*, RC_
* NOVIRTUALKEYCODES - VK_*
* NOWINMESSAGES - WM_*, EM_*, LB_*, CB_*
* NOWINSTYLES - WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
* NOSYSMETRICS - SM_*
* NOMENUS - MF_*
* NOICONS - IDI_*
* NOKEYSTATES - MK_*
* NOSYSCOMMANDS - SC_*
* NORASTEROPS - Binary and Tertiary raster ops
* NOSHOWWINDOW - SW_*
* OEMRESOURCE - OEM Resource values
* NOATOM - Atom Manager routines
* NOCLIPBOARD - Clipboard routines
* NOCOLOR - Screen colors
* NOCTLMGR - Control and Dialog routines
* NODRAWTEXT - DrawText() and DT_*
* NOGDI - All GDI defines and routines
* NOKERNEL - All KERNEL defines and routines
* NOUSER - All USER defines and routines
* NONLS - All NLS defines and routines
* NOMB - MB_* and MessageBox()
* NOMEMMGR - GMEM_*, LMEM_*, GHND, LHND, associated routines
* NOMETAFILE - typedef METAFILEPICT
* NOMINMAX - Macros min(a,b) and max(a,b)
* NOMSG - typedef MSG and associated routines
* NOOPENFILE - OpenFile(), OemToAnsi, AnsiToOem, and OF_*
* NOSCROLL - SB_* and scrolling routines
* NOSERVICE - All Service Controller routines, SERVICE_ equates, etc.
* NOSOUND - Sound driver routines
* NOTEXTMETRIC - typedef TEXTMETRIC and associated routines
* NOWH - SetWindowsHook and WH_*
* NOWINOFFSETS - GWL_*, GCL_*, associated routines
* NOCOMM - COMM driver routines
* NOKANJI - Kanji support stuff.
* NOHELP - Help engine interface.
* NOPROFILER - Profiler interface.
* NODEFERWINDOWPOS - DeferWindowPos routines
* NOMCX - Modem Configuration Extensions
*/

Intrusive defines in windows headers

Realistically, I think the cleanest solution would be to provide a wrapper header that would #include <windows.h> and #undef all the macros that are getting in your way. You would then include this wrapper header instead of windows.h.

How do I avoid name collision with macros defined in Windows header files?

You will be better off if you just rename your CreateDirectory method. If you need to use windows APIs, fighting with Windows.h is a losing battle.

Incidently, if you were consistent in including windows.h, this will still be compiling. (although you might have problems in other places).

Disabling PlaySound() that is included by LibCURL

The #defines you mention are Win32 SDK defines. They instruct windows.h (more accurately, various other Win32 headers that windows.h itself #includes) to not define/declare various symbols.

The #define you are looking for to omit a declaration of PlaySound(A|W) (in mmsystem.h) is:

#define MMNOSOUND

Here is the full table of defines in mmsystem.h:

 *  Define:         Prevent inclusion of:
* -------------- --------------------------------------------------------
* MMNODRV Installable driver support
* MMNOSOUND Sound support
* MMNOWAVE Waveform support
* MMNOMIDI MIDI support
* MMNOAUX Auxiliary audio support
* MMNOMIXER Mixer support
* MMNOTIMER Timer support
* MMNOJOY Joystick support
* MMNOMCI MCI support
* MMNOMMIO Multimedia file I/O support
* MMNOMMSYSTEM General MMSYSTEM functions

Alternatively:

#define WIN32_LEAN_AND_MEAN

Which will prevent windows.h from #include'ing a bunch of headers, including mmsystem.h.

Where did WIN32_LEAN_AND_MEAN come from?

macro and member function conflict

The workaround is to use the parenthesis: int max = (std::numeric_limits<int>::max)();

It allows you to include the windef.h, doesn't require you to #undef max (which may have adverse side effects) and there is no need to #define NOMINMAX. Works like a charm!

Possible problems with NOMINMAX on Visual C++

Using NOMINMAX is the only not-completely-evil way to include <windows.h>. You should also define UNICODE and STRICT. Although the latter is defined by default by modern implementations.

You can however run into problems with Microsoft’s headers, e.g. for GdiPlus. I’m not aware of problems with headers from any other companies or persons.

If the header defines a namespace, as GdiPlus does, then one fix is to create a wrapper for the relevant header, where you include <algorithm>, and inside the header’s namespace, using namespace std; (or alternatively using std::min; and using std::max):

#define NOMINMAX
#include <algorithm>
namespace Gdiplus
{
using std::min;
using std::max;
}

Note that that is very different from a using namespace std; at global scope in header, which one should never do.

I don’t know of any good workaround for the case where there's no namespace, but happily I haven’t run into that, so in practice that particular problem is probably moot.

Unresolved External Symbol when using dllexport and specific function name

It's due to a quirk in the Windows headers. When you #include <windows.h>, it #defines the symbol GetMessage to either GetMessageA or GetMessageW, depending on whether or not you have Unicode support enabled (more specifically, if the UNICODE macro is defined) -- see Unicode in the Windows API and Conventions for Function Prototypes for more info on that.

To work around this, you have a few options:

  • Don't include the Windows headers
  • Define the macro NOMSG before include <windows.h> -- this will suppress the declarations of various message-related functions and macros
  • #undef GetMessage before your class definition
  • Rename your function to something else

Conflict between a namespace and a define

Generally, you should avoid using all-caps identifiers as they are used for macros. In this case, I'd rename the namespace.

(As a side note, <windows.h> #defines other stuff like GetPrinter and indeed it gets annoying. I usually go with #undef then. It also helps to only include <windows.h> in .cpp files and make sure the scope affected by the header is as small as possible.)



Related Topics



Leave a reply



Submit