diff --git a/native/cocos/application/BaseGame.cpp b/native/cocos/application/BaseGame.cpp index 73b774e7f4c..1462e46fcb3 100644 --- a/native/cocos/application/BaseGame.cpp +++ b/native/cocos/application/BaseGame.cpp @@ -58,7 +58,8 @@ int BaseGame::init() { _windowInfo.height = _windowInfo.height == -1 ? 600 : _windowInfo.height; _windowInfo.flags = _windowInfo.flags == -1 ? cc::ISystemWindow::CC_WINDOW_SHOWN | cc::ISystemWindow::CC_WINDOW_RESIZABLE | - cc::ISystemWindow::CC_WINDOW_INPUT_FOCUS + cc::ISystemWindow::CC_WINDOW_INPUT_FOCUS | + cc::ISystemWindow::CC_WINDOW_ALLOW_HIGHDPI : _windowInfo.flags; std::call_once(_windowCreateFlag, [&]() { ISystemWindowInfo info; diff --git a/native/cocos/platform/SDLHelper.cpp b/native/cocos/platform/SDLHelper.cpp index 84b762f6b22..815fbd4588a 100644 --- a/native/cocos/platform/SDLHelper.cpp +++ b/native/cocos/platform/SDLHelper.cpp @@ -155,6 +155,9 @@ SDLHelper::~SDLHelper() { } int SDLHelper::init() { +#if CC_PLATFORM == CC_PLATFORM_WINDOWS + SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0"); +#endif if (SDL_Init(SDL_INIT_VIDEO) < 0) { // Display error message CC_LOG_ERROR("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); @@ -195,20 +198,30 @@ void SDLHelper::dispatchWindowEvent(uint32_t windowId, const SDL_WindowEvent &we break; } case SDL_WINDOWEVENT_SIZE_CHANGED: { - auto *screen = BasePlatform::getPlatform()->getInterface(); - CC_ASSERT(screen != nullptr); ev.type = WindowEvent::Type::SIZE_CHANGED; +#if CC_PLATFORM == CC_PLATFORM_WINDOWS + ev.width = wevent.data1; + ev.height = wevent.data2; +#else + auto *screen = BasePlatform::getPlatform()->getInterface(); + CC_ASSERT(screen != nullptr); ev.width = wevent.data1 * screen->getDevicePixelRatio(); ev.height = wevent.data2 * screen->getDevicePixelRatio(); +#endif events::WindowEvent::broadcast(ev); break; } case SDL_WINDOWEVENT_RESIZED: { + ev.type = WindowEvent::Type::RESIZED; +#if CC_PLATFORM == CC_PLATFORM_WINDOWS + ev.width = wevent.data1; + ev.height = wevent.data2; +#else auto *screen = BasePlatform::getPlatform()->getInterface(); CC_ASSERT(screen != nullptr); - ev.type = WindowEvent::Type::RESIZED; ev.width = wevent.data1 * screen->getDevicePixelRatio(); ev.height = wevent.data2 * screen->getDevicePixelRatio(); +#endif events::WindowEvent::broadcast(ev); break; } @@ -315,6 +328,7 @@ void SDLHelper::dispatchSDLEvent(uint32_t windowId, const SDL_Event &sdlEvent) { const SDL_TouchFingerEvent &event = sdlEvent.tfinger; touch.type = TouchEvent::Type::ENDED; touch.touches = {TouchInfo(event.x, event.y, (int)event.fingerId)}; + touch.windowId = event.windowID; events::Touch::broadcast(touch); break; } @@ -322,6 +336,7 @@ void SDLHelper::dispatchSDLEvent(uint32_t windowId, const SDL_Event &sdlEvent) { const SDL_TouchFingerEvent &event = sdlEvent.tfinger; touch.type = TouchEvent::Type::BEGAN; touch.touches = {TouchInfo(event.x, event.y, (int)event.fingerId)}; + touch.windowId = event.windowID; events::Touch::broadcast(touch); break; } @@ -329,6 +344,7 @@ void SDLHelper::dispatchSDLEvent(uint32_t windowId, const SDL_Event &sdlEvent) { const SDL_TouchFingerEvent &event = sdlEvent.tfinger; touch.type = TouchEvent::Type::MOVED; touch.touches = {TouchInfo(event.x, event.y, (int)event.fingerId)}; + touch.windowId = event.windowID; events::Touch::broadcast(touch); break; } diff --git a/native/cocos/platform/win32/modules/Screen.cpp b/native/cocos/platform/win32/modules/Screen.cpp index a86c9cfecf6..e1ab5267ae9 100644 --- a/native/cocos/platform/win32/modules/Screen.cpp +++ b/native/cocos/platform/win32/modules/Screen.cpp @@ -31,19 +31,26 @@ namespace cc { int Screen::getDPI() const { + // 参考:https://learn.microsoft.com/zh-cn/windows/win32/api/wingdi/nf-wingdi-getdevicecaps static int dpi = -1; if (dpi == -1) { + + dpi = 96; HDC hScreenDC = GetDC(nullptr); - int PixelsX = GetDeviceCaps(hScreenDC, HORZRES); - int MMX = GetDeviceCaps(hScreenDC, HORZSIZE); - ReleaseDC(nullptr, hScreenDC); - dpi = static_cast(254.0f * PixelsX / MMX / 10); + if (hScreenDC) { + // LOGPIXELSX 对应水平方向每逻辑英寸的像素点数 + dpi = GetDeviceCaps(hScreenDC, LOGPIXELSX); + ReleaseDC(nullptr, hScreenDC); + } + // win10 1607 以上 + // HWND hDesktop = GetDesktopWindow(); + // dpi = GetDpiForWindow(hDesktop); } return dpi; } float Screen::getDevicePixelRatio() const { - return 1; + return getDPI() / 96.0f; } void Screen::setKeepScreenOn(bool value) { @@ -73,4 +80,4 @@ void Screen::setDisplayStats(bool isShow) { se::ScriptEngine::getInstance()->evalString(commandBuf); } -} // namespace cc \ No newline at end of file +} // namespace cc diff --git a/native/cocos/platform/win32/modules/SystemWindow.cpp b/native/cocos/platform/win32/modules/SystemWindow.cpp index 1d58d8c081f..29f21204dfa 100644 --- a/native/cocos/platform/win32/modules/SystemWindow.cpp +++ b/native/cocos/platform/win32/modules/SystemWindow.cpp @@ -29,6 +29,7 @@ #include "engine/EngineEvents.h" #include "platform/SDLHelper.h" #include "platform/win32/WindowsPlatform.h" +#include "platform/interfaces/modules/IScreen.h" namespace cc { SystemWindow::SystemWindow(uint32_t windowId, void *externalHandle) @@ -45,13 +46,14 @@ SystemWindow::~SystemWindow() { bool SystemWindow::createWindow(const char *title, int w, int h, int flags) { - _window = SDLHelper::createWindow(title, w, h, flags); + float dpr = cc::BasePlatform::getPlatform()->getInterface()->getDevicePixelRatio(); + _width = w * dpr; + _height = h * dpr; + _window = SDLHelper::createWindow(title, _width, _height, flags); if (!_window) { return false; } - _width = w; - _height = h; _windowHandle = SDLHelper::getWindowHandle(_window); return true; } @@ -59,13 +61,15 @@ bool SystemWindow::createWindow(const char *title, bool SystemWindow::createWindow(const char *title, int x, int y, int w, int h, int flags) { - _window = SDLHelper::createWindow(title, x, y, w, h, flags); + float dpr = cc::BasePlatform::getPlatform()->getInterface()->getDevicePixelRatio(); + _width = w * dpr; + _height = h * dpr; + + _window = SDLHelper::createWindow(title, x, y, _width, _height, flags); if (!_window) { return false; } - _width = w; - _height = h; _windowHandle = SDLHelper::getWindowHandle(_window); return true; diff --git a/native/cocos/ui/edit-box/EditBox-win32.cpp b/native/cocos/ui/edit-box/EditBox-win32.cpp index 9addf641c44..c2b416f9635 100644 --- a/native/cocos/ui/edit-box/EditBox-win32.cpp +++ b/native/cocos/ui/edit-box/EditBox-win32.cpp @@ -28,6 +28,7 @@ #include "cocos/bindings/manual/jsb_global.h" #include "cocos/platform/interfaces/modules/ISystemWindow.h" #include "cocos/platform/interfaces/modules/ISystemWindowManager.h" +#include "platform/interfaces/modules/IScreen.h" #include #include @@ -214,16 +215,17 @@ void EditBox::show(const EditBox::ShowInfo &showInfo) { g_prevMainWindowProc = (WNDPROC)SetWindowLongPtr(parent, GWLP_WNDPROC, (LONG_PTR)mainWindowProc); g_prevEditWindowProc = (WNDPROC)SetWindowLongPtr(g_hwndEditBox, GWLP_WNDPROC, (LONG_PTR)editWindowProc); } - + auto *screen = BasePlatform::getPlatform()->getInterface(); + float dpr = screen->getDevicePixelRatio(); ::SendMessageW(g_hwndEditBox, EM_LIMITTEXT, showInfo.maxLength, 0); // SendMessage(g_hwndEditBox, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); SetWindowPos(g_hwndEditBox, HWND_NOTOPMOST, - showInfo.x, - windowHeight - showInfo.y - showInfo.height, - showInfo.width, - showInfo.height, + showInfo.x * dpr, + windowHeight - showInfo.y * dpr - showInfo.height * dpr, + showInfo.width * dpr, + showInfo.height * dpr, SWP_NOZORDER); ::SetWindowTextW(g_hwndEditBox, str2ws(showInfo.defaultValue).c_str()); @@ -243,7 +245,7 @@ void EditBox::show(const EditBox::ShowInfo &showInfo) { RECT rect; GetWindowRect(getCurrentWindowHwnd(), &rect); - float WindowRatio = (float)(rect.bottom - rect.top) / (float)CC_GET_MAIN_SYSTEM_WINDOW()->getViewSize().height; + float WindowRatio = (float)(rect.bottom - rect.top) / (float)CC_GET_MAIN_SYSTEM_WINDOW()->getViewSize().height * dpr; float JsFontRatio = float(showInfo.fontSize) / 5; /** A probale way to calculate the increase of font size * OriginalSize + Increase = OriginalSize * Ratio_of_js_fontSize * Ratio_of_window diff --git a/native/tools/simulator/frameworks/runtime-src/CMakeLists.txt b/native/tools/simulator/frameworks/runtime-src/CMakeLists.txt index e05aa92c7ef..949a20a674e 100644 --- a/native/tools/simulator/frameworks/runtime-src/CMakeLists.txt +++ b/native/tools/simulator/frameworks/runtime-src/CMakeLists.txt @@ -152,6 +152,10 @@ else() add_executable(${LIB_NAME} ${PROJ_SOURCES} ${PROJ_EXTRA_SOURCE}) endif() +if(WINDOWS AND MSVC) + set_property(TARGET ${LIB_NAME} PROPERTY VS_DPI_AWARE "PerMonitor") +endif() + target_link_libraries(${LIB_NAME} ${ENGINE_NAME} simulator) target_include_directories(${LIB_NAME} PRIVATE Classes diff --git a/pal/input/native/mouse-input.ts b/pal/input/native/mouse-input.ts index 45e2bfde9c3..eb7c47012ad 100644 --- a/pal/input/native/mouse-input.ts +++ b/pal/input/native/mouse-input.ts @@ -116,7 +116,10 @@ export class MouseInputSource { private _getLocation (event: jsb.MouseEvent): Vec2 { const window = this._windowManager.getWindow(event.windowId); const windowSize = window.getViewSize(); - const dpr = screenAdapter.devicePixelRatio; + let dpr = screenAdapter.devicePixelRatio; + if (systemInfo.os === OS.WINDOWS) { // 在windows下DPI变化时下发的是实际坐标 + dpr = 1; + } const x = event.x * dpr; const y = windowSize.height - event.y * dpr; return new Vec2(x, y); @@ -187,7 +190,10 @@ export class MouseInputSource { const eventMouse = new EventMouse(eventType, false, this._preMousePos, mouseEvent.windowId); eventMouse.setLocation(location.x, location.y); eventMouse.setButton(button); - const dpr = screenAdapter.devicePixelRatio; + let dpr = screenAdapter.devicePixelRatio; + if (systemInfo.os === OS.WINDOWS) { // 在windows下DPI变化时下发的是实际坐标 + dpr = 1; + } eventMouse.movementX = typeof mouseEvent.xDelta === 'undefined' ? 0 : mouseEvent.xDelta * dpr; eventMouse.movementY = typeof mouseEvent.yDelta === 'undefined' ? 0 : mouseEvent.yDelta * dpr; // update previous mouse position. diff --git a/pal/input/native/touch-input.ts b/pal/input/native/touch-input.ts index 8a2a751f6bb..af25b42279f 100644 --- a/pal/input/native/touch-input.ts +++ b/pal/input/native/touch-input.ts @@ -23,11 +23,13 @@ */ import { screenAdapter } from 'pal/screen-adapter'; +import { systemInfo } from 'pal/system-info'; import { Size, Vec2 } from '../../../cocos/core/math'; import { EventTarget } from '../../../cocos/core/event'; import { EventTouch, Touch as CCTouch } from '../../../cocos/input/types'; import { touchManager } from '../touch-manager'; import { InputEventType } from '../../../cocos/input/types/event-enum'; +import { OS } from '../../system-info/enum-type'; export type TouchCallback = (res: EventTouch) => void; @@ -114,7 +116,11 @@ export class TouchInputSource { private _dispatchEvent (eventType: InputEventType, changedTouches: Touch[], windowId: number): void { const handleTouches: CCTouch[] = []; const length = changedTouches.length; - const windowSize = this._windowManager.getWindow(windowId).getViewSize() as Size; + const window = this._windowManager.getWindow(windowId); + if (window === null) { + return; + } + const windowSize = window.getViewSize() as Size; for (let i = 0; i < length; ++i) { const changedTouch = changedTouches[i]; const touchID = changedTouch.identifier; @@ -144,7 +150,10 @@ export class TouchInputSource { } private _getLocation (touch: globalThis.Touch, windowSize: Size): Vec2 { - const dpr = screenAdapter.devicePixelRatio; + let dpr = screenAdapter.devicePixelRatio; + if (systemInfo.os === OS.WINDOWS) { // 在windows下DPI变化时下发的是实际坐标 + dpr = 1; + } const x = touch.clientX * dpr; const y = windowSize.height - touch.clientY * dpr; return new Vec2(x, y); diff --git a/templates/compatibility-info.json b/templates/compatibility-info.json index f6ce2ecba26..bd654311896 100644 --- a/templates/compatibility-info.json +++ b/templates/compatibility-info.json @@ -1,5 +1,5 @@ { "native": { - "default": ">=3.6.0" + "default": ">=3.8.0" } } \ No newline at end of file diff --git a/templates/windows/CMakeLists.txt b/templates/windows/CMakeLists.txt index 9f3d15f91f8..e000ac49c70 100644 --- a/templates/windows/CMakeLists.txt +++ b/templates/windows/CMakeLists.txt @@ -14,4 +14,5 @@ cc_windows_before_target(${EXECUTABLE_NAME}) add_executable(${EXECUTABLE_NAME} ${CC_ALL_SOURCES} ) +set_property(TARGET ${EXECUTABLE_NAME} PROPERTY VS_DPI_AWARE "PerMonitor") cc_windows_after_target(${EXECUTABLE_NAME}) \ No newline at end of file