Skip to content

Commit 409d27b

Browse files
committed
8321151: JDK-8294427 breaks Windows L&F on all older Windows versions
Backport-of: f695ca588453265d6ad791c6a396197e8a53ba39
1 parent 6788e5f commit 409d27b

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp

+52-11
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
5252
typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
5353
int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
5454

55+
typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
5556
typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
5657

5758
typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
@@ -96,6 +97,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
9697
(HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
9798
int iPropId, DWORD *pdwDuration);
9899

100+
static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
99101
static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
100102
static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
101103
static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
@@ -115,13 +117,17 @@ static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT
115117
IsThemeBackgroundPartiallyTransparentFunc = NULL;
116118
static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDurationFunc = NULL;
117119

120+
constexpr unsigned int defaultDPI = 96;
118121

119-
BOOL InitThemes() {
122+
123+
static BOOL InitThemes() {
120124
static HMODULE hModThemes = NULL;
121125
hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
122126
DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
123127
if(hModThemes) {
124128
DTRACE_PRINTLN("Loaded UxTheme.dll\n");
129+
OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
130+
"OpenThemeData");
125131
OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
126132
hModThemes, "OpenThemeDataForDpi");
127133
DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
@@ -158,7 +164,7 @@ BOOL InitThemes() {
158164
(PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
159165
"GetThemeTransitionDuration");
160166

161-
if(OpenThemeDataForDpiFunc
167+
if((OpenThemeDataForDpiFunc || OpenThemeDataFunc)
162168
&& DrawThemeBackgroundFunc
163169
&& CloseThemeDataFunc
164170
&& DrawThemeTextFunc
@@ -179,10 +185,12 @@ BOOL InitThemes() {
179185
DTRACE_PRINTLN("Loaded function pointers.\n");
180186
// We need to make sure we can load the Theme.
181187
// Use the default DPI value of 96 on windows.
182-
constexpr unsigned int defaultDPI = 96;
183-
HTHEME hTheme = OpenThemeDataForDpiFunc (
184-
AwtToolkit::GetInstance().GetHWnd(),
185-
L"Button", defaultDPI);
188+
HTHEME hTheme = OpenThemeDataForDpiFunc
189+
? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(),
190+
L"Button", defaultDPI)
191+
: OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(),
192+
L"Button");
193+
186194
if(hTheme) {
187195
DTRACE_PRINTLN("Loaded Theme data.\n");
188196
CloseThemeDataFunc(hTheme);
@@ -252,11 +260,13 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
252260
JNU_ThrowOutOfMemoryError(env, 0);
253261
return 0;
254262
}
263+
255264
// We need to open the Theme on a Window that will stick around.
256265
// The best one for that purpose is the Toolkit window.
257-
HTHEME htheme = OpenThemeDataForDpiFunc(
258-
AwtToolkit::GetInstance().GetHWnd(),
259-
str, dpi);
266+
HTHEME htheme = OpenThemeDataForDpiFunc
267+
? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi)
268+
: OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
269+
260270
JNU_ReleaseStringPlatformChars(env, widget, str);
261271
return (jlong) htheme;
262272
}
@@ -436,9 +446,14 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
436446

437447
rect.left = 0;
438448
rect.top = 0;
439-
rect.bottom = rectBottom;
440-
rect.right = rectRight;
441449

450+
if (OpenThemeDataForDpiFunc) {
451+
rect.bottom = rectBottom;
452+
rect.right = rectRight;
453+
} else {
454+
rect.bottom = h;
455+
rect.right = w;
456+
}
442457
ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
443458

444459
HRESULT hres = DrawThemeBackgroundFunc(hTheme, memDC, part, state, &rect, NULL);
@@ -461,6 +476,28 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
461476
ReleaseDC(NULL,defaultDC);
462477
}
463478

479+
static void rescale(SIZE *size) {
480+
static int dpiX = -1;
481+
static int dpiY = -1;
482+
483+
if (dpiX == -1 || dpiY == -1) {
484+
HWND hWnd = ::GetDesktopWindow();
485+
HDC hDC = ::GetDC(hWnd);
486+
dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
487+
dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
488+
::ReleaseDC(hWnd, hDC);
489+
}
490+
491+
if (dpiX !=0 && dpiX != defaultDPI) {
492+
float invScaleX = (float) defaultDPI / dpiX;
493+
size->cx = (int) round(size->cx * invScaleX);
494+
}
495+
if (dpiY != 0 && dpiY != defaultDPI) {
496+
float invScaleY = (float) defaultDPI / dpiY;
497+
size->cy = (int) round(size->cy * invScaleY);
498+
}
499+
}
500+
464501
jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
465502
if (env->EnsureLocalCapacity(2) < 0) {
466503
return NULL;
@@ -752,6 +789,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
752789
CHECK_NULL_RETURN(dimMID, NULL);
753790
}
754791

792+
if (!OpenThemeDataForDpiFunc) {
793+
rescale(&size);
794+
}
795+
755796
jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
756797
if (safe_ExceptionOccurred(env)) {
757798
env->ExceptionDescribe();

0 commit comments

Comments
 (0)