Direct2D QPA: Check Direct2D version

Since we require a relatively recent system, check the version of the
direct2d dll on disk and report an error to the user if it is too old.
Previously only a cryptic runtime error resulted from a direct2d version
that was too old.

Change-Id: I6c3955e1a98326fca6bcdc871b0a25291391ba88
Reviewed-by: Risto Avila <risto.avila@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
Louai Al-Khanji 2014-05-05 14:49:04 +03:00 committed by The Qt Project
parent bfa0d149f6
commit 70accc289a
2 changed files with 135 additions and 2 deletions

View File

@ -9,7 +9,7 @@ QT *= core-private
QT *= gui-private
QT *= platformsupport-private
LIBS *= -ld2d1 -ld3d11 -ldwrite
LIBS *= -ld2d1 -ld3d11 -ldwrite -lVersion
include(../windows/windows.pri)

View File

@ -48,7 +48,8 @@
#include "qwindowscontext.h"
#include <QtCore/QDebug>
#include <qplatformdefs.h>
#include <QtCore/QCoreApplication>
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
@ -61,8 +62,140 @@ public:
QWindowsDirect2DContext m_d2dContext;
};
class Direct2DVersion
{
private:
Direct2DVersion()
: partOne(0)
, partTwo(0)
, partThree(0)
, partFour(0)
{}
Direct2DVersion(int one, int two, int three, int four)
: partOne(one)
, partTwo(two)
, partThree(three)
, partFour(four)
{}
public:
// 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update
enum {
D2DMinVersionPart1 = 6,
D2DMinVersionPart2 = 2,
D2DMinVersionPart3 = 9200,
D2DMinVersionPart4 = 16765
};
static Direct2DVersion systemVersion() {
static const int bufSize = 512;
TCHAR filename[bufSize];
UINT i = GetSystemDirectory(filename, bufSize);
if (i > 0 && i < MAX_PATH) {
if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) {
DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (versionInfoSize) {
QVector<BYTE> info(versionInfoSize);
if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) {
UINT size;
DWORD *fi;
if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) {
VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi;
return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS),
LOWORD(verInfo->dwFileVersionMS),
HIWORD(verInfo->dwFileVersionLS),
LOWORD(verInfo->dwFileVersionLS));
}
}
}
}
}
return Direct2DVersion();
}
static Direct2DVersion minimumVersion() {
return Direct2DVersion(D2DMinVersionPart1,
D2DMinVersionPart2,
D2DMinVersionPart3,
D2DMinVersionPart4);
}
bool isValid() const {
return partOne || partTwo || partThree || partFour;
}
bool operator<(const Direct2DVersion &other) {
int c = cmp(partOne, other.partOne);
if (c > 0)
return false;
if (c < 0)
return true;
c = cmp(partTwo, other.partTwo);
if (c > 0)
return false;
if (c < 0)
return true;
c = cmp(partThree, other.partThree);
if (c > 0)
return false;
if (c < 0)
return true;
c = cmp(partFour, other.partFour);
if (c > 0)
return false;
if (c < 0)
return true;
return false;
}
static Q_DECL_CONSTEXPR int cmp(int a, int b) {
return a - b;
}
int partOne, partTwo, partThree, partFour;
};
QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
{
Direct2DVersion systemVersion = Direct2DVersion::systemVersion();
if (systemVersion.isValid() && systemVersion < Direct2DVersion::minimumVersion()) {
QString msg = QCoreApplication::translate("QWindowsDirect2DIntegration",
"Qt cannot load the direct2d platform plugin because " \
"the Direct2D version on this system is too old. The " \
"minimum system requirement for this platform plugin " \
"is Windows 7 SP1 with Platform Update.\n\n" \
"The minimum Direct2D version required is %1.%2.%3.%4. " \
"The Direct2D version on this system is %5.%6.%7.%8.");
msg = msg.arg(Direct2DVersion::D2DMinVersionPart1)
.arg(Direct2DVersion::D2DMinVersionPart2)
.arg(Direct2DVersion::D2DMinVersionPart3)
.arg(Direct2DVersion::D2DMinVersionPart4)
.arg(systemVersion.partOne)
.arg(systemVersion.partTwo)
.arg(systemVersion.partThree)
.arg(systemVersion.partFour);
QString caption = QCoreApplication::translate("QWindowsDirect2DIntegration",
"Cannot load direct2d platform plugin");
MessageBoxW(NULL,
msg.toStdWString().c_str(),
caption.toStdWString().c_str(),
MB_OK | MB_ICONERROR);
return Q_NULLPTR;
}
QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
if (!integration->init()) {