Skip to content
This repository was archived by the owner on Jul 17, 2024. It is now read-only.
/ jdk22u Public archive

Commit 160f650

Browse files
rajamahaivanov-jdk
authored andcommitted
8321151: JDK-8294427 breaks Windows L&F on all older Windows versions
Backport-of: f695ca588453265d6ad791c6a396197e8a53ba39
1 parent bbbc0ea commit 160f650

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
@@ -46,6 +46,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
4646
typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
4747
int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
4848

49+
typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
4950
typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
5051

5152
typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
@@ -90,6 +91,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
9091
(HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
9192
int iPropId, DWORD *pdwDuration);
9293

94+
static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
9395
static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
9496
static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
9597
static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
@@ -109,13 +111,17 @@ static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT
109111
IsThemeBackgroundPartiallyTransparentFunc = NULL;
110112
static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDurationFunc = NULL;
111113

114+
constexpr unsigned int defaultDPI = 96;
112115

113-
BOOL InitThemes() {
116+
117+
static BOOL InitThemes() {
114118
static HMODULE hModThemes = NULL;
115119
hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
116120
DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
117121
if(hModThemes) {
118122
DTRACE_PRINTLN("Loaded UxTheme.dll\n");
123+
OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
124+
"OpenThemeData");
119125
OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
120126
hModThemes, "OpenThemeDataForDpi");
121127
DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
@@ -152,7 +158,7 @@ BOOL InitThemes() {
152158
(PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
153159
"GetThemeTransitionDuration");
154160

155-
if(OpenThemeDataForDpiFunc
161+
if((OpenThemeDataForDpiFunc || OpenThemeDataFunc)
156162
&& DrawThemeBackgroundFunc
157163
&& CloseThemeDataFunc
158164
&& DrawThemeTextFunc
@@ -173,10 +179,12 @@ BOOL InitThemes() {
173179
DTRACE_PRINTLN("Loaded function pointers.\n");
174180
// We need to make sure we can load the Theme.
175181
// Use the default DPI value of 96 on windows.
176-
constexpr unsigned int defaultDPI = 96;
177-
HTHEME hTheme = OpenThemeDataForDpiFunc (
178-
AwtToolkit::GetInstance().GetHWnd(),
179-
L"Button", defaultDPI);
182+
HTHEME hTheme = OpenThemeDataForDpiFunc
183+
? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(),
184+
L"Button", defaultDPI)
185+
: OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(),
186+
L"Button");
187+
180188
if(hTheme) {
181189
DTRACE_PRINTLN("Loaded Theme data.\n");
182190
CloseThemeDataFunc(hTheme);
@@ -246,11 +254,13 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
246254
JNU_ThrowOutOfMemoryError(env, 0);
247255
return 0;
248256
}
257+
249258
// We need to open the Theme on a Window that will stick around.
250259
// The best one for that purpose is the Toolkit window.
251-
HTHEME htheme = OpenThemeDataForDpiFunc(
252-
AwtToolkit::GetInstance().GetHWnd(),
253-
str, dpi);
260+
HTHEME htheme = OpenThemeDataForDpiFunc
261+
? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi)
262+
: OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
263+
254264
JNU_ReleaseStringPlatformChars(env, widget, str);
255265
return (jlong) htheme;
256266
}
@@ -430,9 +440,14 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
430440

431441
rect.left = 0;
432442
rect.top = 0;
433-
rect.bottom = rectBottom;
434-
rect.right = rectRight;
435443

444+
if (OpenThemeDataForDpiFunc) {
445+
rect.bottom = rectBottom;
446+
rect.right = rectRight;
447+
} else {
448+
rect.bottom = h;
449+
rect.right = w;
450+
}
436451
ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
437452

438453
HRESULT hres = DrawThemeBackgroundFunc(hTheme, memDC, part, state, &rect, NULL);
@@ -455,6 +470,28 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
455470
ReleaseDC(NULL,defaultDC);
456471
}
457472

473+
static void rescale(SIZE *size) {
474+
static int dpiX = -1;
475+
static int dpiY = -1;
476+
477+
if (dpiX == -1 || dpiY == -1) {
478+
HWND hWnd = ::GetDesktopWindow();
479+
HDC hDC = ::GetDC(hWnd);
480+
dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
481+
dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
482+
::ReleaseDC(hWnd, hDC);
483+
}
484+
485+
if (dpiX !=0 && dpiX != defaultDPI) {
486+
float invScaleX = (float) defaultDPI / dpiX;
487+
size->cx = (int) round(size->cx * invScaleX);
488+
}
489+
if (dpiY != 0 && dpiY != defaultDPI) {
490+
float invScaleY = (float) defaultDPI / dpiY;
491+
size->cy = (int) round(size->cy * invScaleY);
492+
}
493+
}
494+
458495
jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
459496
if (env->EnsureLocalCapacity(2) < 0) {
460497
return NULL;
@@ -746,6 +783,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
746783
CHECK_NULL_RETURN(dimMID, NULL);
747784
}
748785

786+
if (!OpenThemeDataForDpiFunc) {
787+
rescale(&size);
788+
}
789+
749790
jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
750791
if (safe_ExceptionOccurred(env)) {
751792
env->ExceptionDescribe();

0 commit comments

Comments
 (0)