Правильный способ справиться с этим совсем не с препроцессором. Вместо этого вам нужно использовать функцию Win32 API GetProcAddress()
во время выполнения, например:
typedef BOOL (WINAPI *LPFN_EDM)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
LPFN_EDM lpEnumDisplayMonitors = (LPFN_EDM) GetProcAddress(GetModuleHandle("user32.dll"), "EnumDisplayMonitors");
if (lpEnumDisplayMonitors)
{
// use lpEnumDisplayMonitors as needed...
}
else
{
// use something else...
}
Это даже описано в документации Microsoft:
Эксплуатация Версия системы
Идентификация текущей операционной системы обычно не лучший способ определить, присутствует ли конкретная функция операционной системы. Это связано с тем, что в операционной системе могут быть добавлены новые функции в распространяемой DLL. Вместо использования функций Помощника по API Версии для определения платформы или номера версии операционной системы, проверьте наличие самой функции.
Чтобы определить лучший способ проверки функции, обратитесь к документации для Интересная особенность. В следующем списке обсуждаются некоторые распространенные методы обнаружения объектов:
Вы можете проверить наличие функций, связанных с функцией. Чтобы проверить наличие функции в системной DLL, вызовите функцию LoadLibrary
для загрузки DLL. Затем вызовите функцию GetProcAddress
, чтобы определить, присутствует ли интересующая функция в DLL. Используйте указатель, возвращаемый GetProcAddress
для вызова функции. Обратите внимание, что даже если функция присутствует, это может быть заглушка, которая просто возвращает код ошибки, такой как ERROR_CALL_NOT_IMPLEMENTED
.
Вы можете определить наличие некоторых функций с помощью GetSystemMetrics
функция. Например, вы можете обнаружить несколько мониторов, набрав GetSystemMetrics(SM_CMONITORS)
. Существует несколько версий распространяемых библиотек DLL, которые реализуют функции оболочки и общие элементы управления. Информацию о том, какие версии присутствуют в системе, в которой работает ваше приложение, см. В разделе Версии оболочки и общих элементов управления .
Если ваш компилятор toolchain поддерживает Delay Loading , тогда вы можете использовать это вместо вызова GetProcAddress()
вручную. Установите для своего проекта задержку загрузки user32.dll
, а затем, как правило, после EnumDisplayMonitors()
вызывайте *1043*, как обычно, после проверки ОС поддерживает то, что вам нужно, например, проверяет, является ли Windows Win2K или более поздней, через GetVersionEx()
или проверка установки нескольких мониторов, например:
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
if (osvi.dwMajorVersion >= 5) // Win2K = 5.0
{
// use EnumDisplayMonitors as needed...
}
else
{
// use something else...
}
if (GetSystemMetrics(SM_CMONITORS) > 1)
{
// use EnumDisplayMonitors as needed...
}
else
{
// use something else...
}