Skip to content

Commit a60a5c4

Browse files
committed
8321151: JDK-8294427 breaks Windows L&F on all older Windows versions
Backport-of: f695ca588453265d6ad791c6a396197e8a53ba39
1 parent 93c5f7c commit a60a5c4

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

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
9090
typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
9191
int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect);
9292

93+
typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
9394
typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
9495

9596
typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
@@ -134,6 +135,7 @@ typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
134135
(HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
135136
int iPropId, DWORD *pdwDuration);
136137

138+
static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
137139
static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
138140
static PFNDRAWTHEMEBACKGROUND DrawThemeBackground = NULL;
139141
static PFNCLOSETHEMEDATA CloseThemeData = NULL;
@@ -154,13 +156,17 @@ static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT
154156
//this function might not exist on Windows XP
155157
static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDuration = NULL;
156158

159+
constexpr unsigned int defaultDPI = 96;
157160

158-
BOOL InitThemes() {
161+
162+
static BOOL InitThemes() {
159163
static HMODULE hModThemes = NULL;
160164
hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
161165
DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
162166
if(hModThemes) {
163167
DTRACE_PRINTLN("Loaded UxTheme.dll\n");
168+
OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
169+
"OpenThemeData");
164170
OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
165171
hModThemes, "OpenThemeDataForDpi");
166172
DrawThemeBackground = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
@@ -198,7 +204,7 @@ BOOL InitThemes() {
198204
(PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
199205
"GetThemeTransitionDuration");
200206

201-
if(OpenThemeDataForDpiFunc
207+
if((OpenThemeDataForDpiFunc || OpenThemeDataFunc)
202208
&& DrawThemeBackground
203209
&& CloseThemeData
204210
&& DrawThemeText
@@ -218,10 +224,12 @@ BOOL InitThemes() {
218224
DTRACE_PRINTLN("Loaded function pointers.\n");
219225
// We need to make sure we can load the Theme.
220226
// Use the default DPI value of 96 on windows.
221-
constexpr unsigned int defaultDPI = 96;
222-
HTHEME hTheme = OpenThemeDataForDpiFunc (
223-
AwtToolkit::GetInstance().GetHWnd(),
224-
L"Button", defaultDPI);
227+
HTHEME hTheme = OpenThemeDataForDpiFunc
228+
? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(),
229+
L"Button", defaultDPI)
230+
: OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(),
231+
L"Button");
232+
225233
if(hTheme) {
226234
DTRACE_PRINTLN("Loaded Theme data.\n");
227235
CloseThemeData(hTheme);
@@ -285,11 +293,13 @@ JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
285293
JNU_ThrowOutOfMemoryError(env, 0);
286294
return 0;
287295
}
296+
288297
// We need to open the Theme on a Window that will stick around.
289298
// The best one for that purpose is the Toolkit window.
290-
HTHEME htheme = OpenThemeDataForDpiFunc(
291-
AwtToolkit::GetInstance().GetHWnd(),
292-
str, dpi);
299+
HTHEME htheme = OpenThemeDataForDpiFunc
300+
? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi)
301+
: OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
302+
293303
JNU_ReleaseStringPlatformChars(env, widget, str);
294304
return (jlong) htheme;
295305
}
@@ -469,9 +479,14 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
469479

470480
rect.left = 0;
471481
rect.top = 0;
472-
rect.bottom = rectBottom;
473-
rect.right = rectRight;
474482

483+
if (OpenThemeDataForDpiFunc) {
484+
rect.bottom = rectBottom;
485+
rect.right = rectRight;
486+
} else {
487+
rect.bottom = h;
488+
rect.right = w;
489+
}
475490
ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
476491

477492
HRESULT hres = DrawThemeBackground(hTheme, memDC, part, state, &rect, NULL);
@@ -494,6 +509,28 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
494509
ReleaseDC(NULL,defaultDC);
495510
}
496511

512+
static void rescale(SIZE *size) {
513+
static int dpiX = -1;
514+
static int dpiY = -1;
515+
516+
if (dpiX == -1 || dpiY == -1) {
517+
HWND hWnd = ::GetDesktopWindow();
518+
HDC hDC = ::GetDC(hWnd);
519+
dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
520+
dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
521+
::ReleaseDC(hWnd, hDC);
522+
}
523+
524+
if (dpiX !=0 && dpiX != defaultDPI) {
525+
float invScaleX = (float) defaultDPI / dpiX;
526+
size->cx = (int) round(size->cx * invScaleX);
527+
}
528+
if (dpiY != 0 && dpiY != defaultDPI) {
529+
float invScaleY = (float) defaultDPI / dpiY;
530+
size->cy = (int) round(size->cy * invScaleY);
531+
}
532+
}
533+
497534
jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
498535
if (env->EnsureLocalCapacity(2) < 0) {
499536
return NULL;
@@ -785,6 +822,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
785822
CHECK_NULL_RETURN(dimMID, NULL);
786823
}
787824

825+
if (!OpenThemeDataForDpiFunc) {
826+
rescale(&size);
827+
}
828+
788829
jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
789830
if (safe_ExceptionOccurred(env)) {
790831
env->ExceptionDescribe();

0 commit comments

Comments
 (0)