diff --git a/Import/GacUI.cpp b/Import/GacUI.cpp index 87057634..b2099226 100644 --- a/Import/GacUI.cpp +++ b/Import/GacUI.cpp @@ -199,21 +199,21 @@ GuiApplication } } - void GuiApplication::LeftButtonDown(Point position) + void GuiApplication::LeftButtonDown(NativePoint position) { OnMouseDown(position); } - void GuiApplication::LeftButtonUp(Point position) + void GuiApplication::LeftButtonUp(NativePoint position) { } - void GuiApplication::RightButtonDown(Point position) + void GuiApplication::RightButtonDown(NativePoint position) { OnMouseDown(position); } - void GuiApplication::RightButtonUp(Point position) + void GuiApplication::RightButtonUp(NativePoint position) { } @@ -282,7 +282,7 @@ GuiApplication } } - void GuiApplication::OnMouseDown(Point location) + void GuiApplication::OnMouseDown(NativePoint location) { GuiWindow* window=GetWindow(location); for(vint i=0;iWindowService()->GetWindow(location); if (nativeWindow) @@ -3646,17 +3646,17 @@ GuiControlHost void GuiControlHost::MoveIntoTooltipControl(GuiControl* tooltipControl, Point location) { - if(tooltipLocation!=location) + if (tooltipLocation != location) { - tooltipLocation=location; + tooltipLocation = location; { - GuiControl* currentOwner=GetApplication()->GetTooltipOwner(); - if(currentOwner && currentOwner!=tooltipControl) + GuiControl* currentOwner = GetApplication()->GetTooltipOwner(); + if (currentOwner && currentOwner != tooltipControl) { - if(tooltipCloseDelay) + if (tooltipCloseDelay) { tooltipCloseDelay->Cancel(); - tooltipCloseDelay=0; + tooltipCloseDelay = 0; } GetApplication()->DelayExecuteInMainThread([=]() { @@ -3664,31 +3664,31 @@ GuiControlHost }, TooltipDelayCloseTime); } } - if(!tooltipControl) + if (!tooltipControl) { - if(tooltipOpenDelay) + if (tooltipOpenDelay) { tooltipOpenDelay->Cancel(); - tooltipOpenDelay=0; + tooltipOpenDelay = 0; } } - else if(tooltipOpenDelay) + else if (tooltipOpenDelay) { tooltipOpenDelay->Delay(TooltipDelayOpenTime); } - else if(GetApplication()->GetTooltipOwner()!=tooltipControl) + else if (GetApplication()->GetTooltipOwner() != tooltipControl) { - tooltipOpenDelay=GetApplication()->DelayExecuteInMainThread([this]() + tooltipOpenDelay = GetApplication()->DelayExecuteInMainThread([this]() { - GuiControl* owner=GetTooltipOwner(tooltipLocation); - if(owner) + GuiControl* owner = GetTooltipOwner(tooltipLocation); + if (owner) { - Point offset=owner->GetBoundsComposition()->GetGlobalBounds().LeftTop(); - Point p(tooltipLocation.x-offset.x, tooltipLocation.y-offset.y+24); + Point offset = owner->GetBoundsComposition()->GetGlobalBounds().LeftTop(); + Point p(tooltipLocation.x - offset.x, tooltipLocation.y - offset.y + 24); owner->DisplayTooltip(p); - tooltipOpenDelay=0; + tooltipOpenDelay = 0; - tooltipCloseDelay=GetApplication()->DelayExecuteInMainThread([this, owner]() + tooltipCloseDelay = GetApplication()->DelayExecuteInMainThread([this, owner]() { owner->CloseTooltip(); }, TooltipDelayLifeTime); @@ -3700,10 +3700,10 @@ GuiControlHost void GuiControlHost::MouseMoving(const NativeWindowMouseInfo& info) { - if(!info.left && !info.middle && !info.right) + if (!info.left && !info.middle && !info.right) { - GuiControl* tooltipControl=GetTooltipOwner(tooltipLocation); - MoveIntoTooltipControl(tooltipControl, Point(info.x, info.y)); + GuiControl* tooltipControl = GetTooltipOwner(tooltipLocation); + MoveIntoTooltipControl(tooltipControl, Point(host->GetNativeWindow()->Convert(NativePoint(info.x, info.y)))); } } @@ -3863,9 +3863,9 @@ GuiControlHost void GuiControlHost::ForceCalculateSizeImmediately() { - auto bounds = GetBounds(); + auto size = GetClientSize(); boundsComposition->ForceCalculateSizeImmediately(); - SetBounds(bounds); + SetClientSize(size); } bool GuiControlHost::GetEnabled() @@ -4026,9 +4026,9 @@ GuiControlHost Size GuiControlHost::GetClientSize() { - if(host->GetNativeWindow()) + if (auto window = host->GetNativeWindow()) { - return host->GetNativeWindow()->GetClientSize(); + return window->Convert(window->GetClientSize()); } else { @@ -4038,29 +4038,38 @@ GuiControlHost void GuiControlHost::SetClientSize(Size value) { - if(host->GetNativeWindow()) + if (auto window = host->GetNativeWindow()) { - host->GetNativeWindow()->SetClientSize(value); + host->GetNativeWindow()->SetClientSize(window->Convert(value)); } } - Rect GuiControlHost::GetBounds() + NativePoint GuiControlHost::GetLocation() { - if(host->GetNativeWindow()) + if(auto window = host->GetNativeWindow()) { - return host->GetNativeWindow()->GetBounds(); + return window->GetBounds().LeftTop(); } else { - return Rect(); + return NativePoint(); } } - void GuiControlHost::SetBounds(Rect value) + void GuiControlHost::SetLocation(NativePoint value) { - if(host->GetNativeWindow()) + if (auto window = host->GetNativeWindow()) { - host->GetNativeWindow()->SetBounds(value); + auto bounds = window->GetBounds(); + window->SetBounds(NativeRect(value, bounds.GetSize())); + } + } + + void GuiControlHost::SetBounds(NativePoint location, Size size) + { + if (auto window = host->GetNativeWindow()) + { + window->SetBounds(NativeRect(location, window->Convert(size))); } } @@ -4218,17 +4227,30 @@ GuiWindow ct->SetTitleBar(hasTitleBar); ct->SetMaximized(GetNativeWindow()->GetSizeState() != INativeWindow::Maximized); ct->SetActivated(GetActivated()); - ct->SetCustomFramePadding(Margin(8, 8, 8, 8)); auto window = GetNativeWindow(); if (window) { window->SetIcon(icon); } + UpdateCustomFramePadding(window, ct); + ct->SetIcon(icon ? icon : window ? window->GetIcon() : nullptr); SyncNativeWindowProperties(); } + void GuiWindow::UpdateCustomFramePadding(INativeWindow* window, templates::GuiWindowTemplate* ct) + { + if (auto window = GetNativeWindow()) + { + ct->SetCustomFramePadding(window->Convert(window->GetCustomFramePadding())); + } + else + { + ct->SetCustomFramePadding({8, 8, 8, 8}); + } + } + void GuiWindow::SyncNativeWindowProperties() { if (auto window = GetNativeWindow()) @@ -4258,6 +4280,14 @@ GuiWindow GetControlTemplateObject(true)->SetMaximized(GetNativeWindow()->GetSizeState() != INativeWindow::Maximized); } + void GuiWindow::DpiChanged() + { + if (auto ct = GetControlTemplateObject(false)) + { + UpdateCustomFramePadding(GetNativeWindow(), ct); + } + } + void GuiWindow::OnNativeWindowChanged() { SyncNativeWindowProperties(); @@ -4337,17 +4367,17 @@ GuiWindow { if (screen) { - Rect screenBounds = screen->GetClientBounds(); - Rect windowBounds = GetBounds(); - SetBounds( - Rect( - Point( - screenBounds.Left() + (screenBounds.Width() - windowBounds.Width()) / 2, - screenBounds.Top() + (screenBounds.Height() - windowBounds.Height()) / 2 - ), - windowBounds.GetSize() - ) - ); + if (auto window = host->GetNativeWindow()) + { + NativeRect screenBounds = screen->GetClientBounds(); + NativeSize windowSize = window->GetBounds().GetSize(); + SetLocation( + NativePoint( + screenBounds.Left() + (screenBounds.Width() - windowSize.x) / 2, + screenBounds.Top() + (screenBounds.Height() - windowSize.y) / 2 + ) + ); + } } } @@ -4363,16 +4393,13 @@ GuiWindow { \ VARIABLE = visible; \ ct->Set ## NAME(visible); \ - if (auto window = GetNativeWindow()) \ + auto window = GetNativeWindow(); \ + if (window) \ { \ CONDITION_BREAK \ window->Set ## NAME(visible); \ - ct->SetCustomFramePadding(window->GetCustomFramePadding()); \ - } \ - else \ - { \ - ct->SetCustomFramePadding({}); \ } \ + UpdateCustomFramePadding(window, ct); \ } \ } \ @@ -4465,9 +4492,14 @@ GuiPopup } else { - auto window = GetNativeWindow(); - auto position = CalculatePopupPosition(clientSize, popupType, popupInfo); - window->SetBounds(Rect(position, clientSize)); + auto window = host->GetNativeWindow(); + auto currentClientSize = window->GetClientSize(); + auto currentWindowSize = window->GetBounds().GetSize(); + auto offsetX = currentWindowSize.x - currentClientSize.x; + auto offsetY = currentWindowSize.y - currentClientSize.y; + auto nativeClientSize = window->Convert(clientSize); + auto position = CalculatePopupPosition(NativeSize(nativeClientSize.x + offsetX, nativeClientSize.y + offsetY), popupType, popupInfo); + SetBounds(position, clientSize); } } @@ -4499,103 +4531,103 @@ GuiPopup } } - Point GuiPopup::CalculatePopupPosition(Size size, Point location, INativeScreen* screen) + bool GuiPopup::IsClippedByScreen(NativeSize size, NativePoint location, INativeScreen* screen) { - Rect screenBounds = screen->GetClientBounds(); + NativeRect screenBounds = screen->GetClientBounds(); + NativeRect windowBounds(location, size); + return !screenBounds.Contains(windowBounds.LeftTop()) || !screenBounds.Contains(windowBounds.RightBottom()); + } + + NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, NativePoint location, INativeScreen* screen) + { + NativeRect screenBounds = screen->GetClientBounds(); if (location.x < screenBounds.x1) { location.x = screenBounds.x1; } - else if (location.x + size.x > screenBounds.x2) + else if (location.x + windowSize.x > screenBounds.x2) { - location.x = screenBounds.x2 - size.x; + location.x = screenBounds.x2 - windowSize.x; } if (location.y < screenBounds.y1) { location.y = screenBounds.y1; } - else if (location.y + size.y > screenBounds.y2) + else if (location.y + windowSize.y > screenBounds.y2) { - location.y = screenBounds.y2 - size.y; + location.y = screenBounds.y2 - windowSize.y; } return location; } - bool GuiPopup::IsClippedByScreen(Size size, Point location, INativeScreen* screen) + NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, Rect bounds, bool preferredTopBottomSide) { - Rect screenBounds = screen->GetClientBounds(); - Rect windowBounds(location, size); - return !screenBounds.Contains(windowBounds.LeftTop()) || !screenBounds.Contains(windowBounds.RightBottom()); - } + NativePoint controlClientOffset = controlWindow->Convert(control->GetBoundsComposition()->GetGlobalBounds().LeftTop()); + NativePoint controlWindowOffset = controlWindow->GetClientBoundsInScreen().LeftTop(); + NativeRect targetBounds(controlWindow->Convert(bounds.LeftTop()), controlWindow->Convert(bounds.GetSize())); + targetBounds.x1 += controlClientOffset.x + controlWindowOffset.x; + targetBounds.x2 += controlClientOffset.x + controlWindowOffset.x; + targetBounds.y1 += controlClientOffset.y + controlWindowOffset.y; + targetBounds.y2 += controlClientOffset.y + controlWindowOffset.y; - Point GuiPopup::CalculatePopupPosition(Size size, GuiControl* control, INativeWindow* controlWindow, Rect bounds, bool preferredTopBottomSide) - { - Point controlClientOffset = control->GetBoundsComposition()->GetGlobalBounds().LeftTop(); - Point controlWindowOffset = controlWindow->GetClientBoundsInScreen().LeftTop(); - bounds.x1 += controlClientOffset.x + controlWindowOffset.x; - bounds.x2 += controlClientOffset.x + controlWindowOffset.x; - bounds.y1 += controlClientOffset.y + controlWindowOffset.y; - bounds.y2 += controlClientOffset.y + controlWindowOffset.y; - - Point locations[4]; + NativePoint locations[4]; if (preferredTopBottomSide) { - locations[0] = Point(bounds.x1, bounds.y2); - locations[1] = Point(bounds.x2 - size.x, bounds.y2); - locations[2] = Point(bounds.x1, bounds.y1 - size.y); - locations[3] = Point(bounds.x2 - size.x, bounds.y1 - size.y); + locations[0] = NativePoint(targetBounds.x1, targetBounds.y2); + locations[1] = NativePoint(targetBounds.x2 - windowSize.x, targetBounds.y2); + locations[2] = NativePoint(targetBounds.x1, targetBounds.y1 - windowSize.y); + locations[3] = NativePoint(targetBounds.x2 - windowSize.x, targetBounds.y1 - windowSize.y); } else { - locations[0] = Point(bounds.x2, bounds.y1); - locations[1] = Point(bounds.x2, bounds.y2 - size.y); - locations[2] = Point(bounds.x1 - size.x, bounds.y1); - locations[3] = Point(bounds.x1 - size.x, bounds.y2 - size.y); + locations[0] = NativePoint(targetBounds.x2, targetBounds.y1); + locations[1] = NativePoint(targetBounds.x2, targetBounds.y2 - windowSize.y); + locations[2] = NativePoint(targetBounds.x1 - windowSize.x, targetBounds.y1); + locations[3] = NativePoint(targetBounds.x1 - windowSize.x, targetBounds.y2 - windowSize.y); } auto screen = GetCurrentController()->ScreenService()->GetScreen(controlWindow); for (vint i = 0; i < 4; i++) { - if (!IsClippedByScreen(size, locations[i], screen)) + if (!IsClippedByScreen(windowSize, locations[i], screen)) { - return CalculatePopupPosition(size, locations[i], screen); + return CalculatePopupPosition(windowSize, locations[i], screen); } } - return CalculatePopupPosition(size, locations[0], screen); + return CalculatePopupPosition(windowSize, locations[0], screen); } - Point GuiPopup::CalculatePopupPosition(Size size, GuiControl* control, INativeWindow* controlWindow, Point location) + NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, Point location) { - Point locations[4]; - Rect controlBounds = control->GetBoundsComposition()->GetGlobalBounds(); - - Point controlClientOffset = controlWindow->GetClientBoundsInScreen().LeftTop(); - vint x = controlBounds.x1 + controlClientOffset.x + location.x; - vint y = controlBounds.y1 + controlClientOffset.y + location.y; - return CalculatePopupPosition(size, Point(x, y), GetCurrentController()->ScreenService()->GetScreen(controlWindow)); + NativePoint controlClientOffset = controlWindow->Convert(control->GetBoundsComposition()->GetGlobalBounds().LeftTop()); + NativePoint controlWindowOffset = controlWindow->GetClientBoundsInScreen().LeftTop(); + NativePoint targetLocation = controlWindow->Convert(location); + NativeCoordinate x = controlClientOffset.x + controlWindowOffset.x + targetLocation.x; + NativeCoordinate y = controlClientOffset.y + controlWindowOffset.y + targetLocation.y; + return CalculatePopupPosition(windowSize, NativePoint(x, y), GetCurrentController()->ScreenService()->GetScreen(controlWindow)); } - Point GuiPopup::CalculatePopupPosition(Size size, GuiControl* control, INativeWindow* controlWindow, bool preferredTopBottomSide) + NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, bool preferredTopBottomSide) { Rect bounds(Point(0, 0), control->GetBoundsComposition()->GetBounds().GetSize()); - return CalculatePopupPosition(size, control, controlWindow, bounds, preferredTopBottomSide); + return CalculatePopupPosition(windowSize, control, controlWindow, bounds, preferredTopBottomSide); } - Point GuiPopup::CalculatePopupPosition(Size size, vint popupType, const PopupInfo& popupInfo) + NativePoint GuiPopup::CalculatePopupPosition(NativeSize windowSize, vint popupType, const PopupInfo& popupInfo) { switch (popupType) { case 1: - return CalculatePopupPosition(size, popupInfo._1.location, popupInfo._1.screen); + return CalculatePopupPosition(windowSize, popupInfo._1.location, popupInfo._1.screen); case 2: - return CalculatePopupPosition(size, popupInfo._2.control, popupInfo._2.controlWindow, popupInfo._2.bounds, popupInfo._2.preferredTopBottomSide); + return CalculatePopupPosition(windowSize, popupInfo._2.control, popupInfo._2.controlWindow, popupInfo._2.bounds, popupInfo._2.preferredTopBottomSide); case 3: - return CalculatePopupPosition(size, popupInfo._3.control, popupInfo._3.controlWindow, popupInfo._3.location); + return CalculatePopupPosition(windowSize, popupInfo._3.control, popupInfo._3.controlWindow, popupInfo._3.location); case 4: - return CalculatePopupPosition(size, popupInfo._4.control, popupInfo._4.controlWindow, popupInfo._4.preferredTopBottomSide); + return CalculatePopupPosition(windowSize, popupInfo._4.control, popupInfo._4.controlWindow, popupInfo._4.preferredTopBottomSide); default: CHECK_FAIL(L"vl::presentation::controls::GuiPopup::CalculatePopupPosition(Size, const PopupInfo&)#Internal error."); } @@ -4604,7 +4636,7 @@ GuiPopup void GuiPopup::ShowPopupInternal() { auto window = GetNativeWindow(); - UpdateClientSizeAfterRendering(window->GetBounds().GetSize()); + UpdateClientSizeAfterRendering(window->Convert(window->GetClientSize())); INativeWindow* controlWindow = nullptr; switch (popupType) @@ -4645,13 +4677,13 @@ GuiPopup GetApplication()->RegisterPopupClosed(this); } - void GuiPopup::ShowPopup(Point location, INativeScreen* screen) + void GuiPopup::ShowPopup(NativePoint location, INativeScreen* screen) { if (auto window = GetNativeWindow()) { if (!screen) { - SetBounds(Rect(location, GetBounds().GetSize())); + SetBounds(location, GetClientSize()); screen = GetCurrentController()->ScreenService()->GetScreen(window); } @@ -24445,7 +24477,7 @@ GuiWindowComposition { if (auto window = relatedHostRecord->host->GetNativeWindow()) { - bounds = Rect(Point(0, 0), window->GetClientSize()); + bounds = Rect(Point(0, 0), window->Convert(window->GetClientSize())); } } UpdatePreviousBounds(bounds); @@ -31553,12 +31585,13 @@ GuiGraphicsHost void GuiGraphicsHost::MouseCapture(const NativeWindowMouseInfo& info) { - if(hostRecord.nativeWindow && (info.left || info.middle || info.right)) + if (hostRecord.nativeWindow && (info.left || info.middle || info.right)) { - if(!hostRecord.nativeWindow->IsCapturing() && !info.nonClient) + if (!hostRecord.nativeWindow->IsCapturing() && !info.nonClient) { hostRecord.nativeWindow->RequireCapture(); - mouseCaptureComposition=windowComposition->FindComposition(Point(info.x, info.y), true); + auto point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y)); + mouseCaptureComposition = windowComposition->FindComposition(point, true); } } } @@ -31684,32 +31717,48 @@ GuiGraphicsHost void GuiGraphicsHost::OnMouseInput(const NativeWindowMouseInfo& info, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent) { - GuiGraphicsComposition* composition=0; - if(mouseCaptureComposition) + GuiGraphicsComposition* composition = 0; + if (mouseCaptureComposition) { - composition=mouseCaptureComposition; + composition = mouseCaptureComposition; } else { - composition=windowComposition->FindComposition(Point(info.x, info.y), true); + auto point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y)); + composition = windowComposition->FindComposition(point, true); } - if(composition) + if (composition) { - Rect bounds=composition->GetGlobalBounds(); + Rect bounds = composition->GetGlobalBounds(); + Point point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y)); GuiMouseEventArgs arguments; - (NativeWindowMouseInfo&)arguments=info; - arguments.x-=bounds.x1; - arguments.y-=bounds.y1; + arguments.ctrl = info.ctrl; + arguments.shift = info.shift; + arguments.left = info.left; + arguments.middle = info.middle; + arguments.right = info.right; + arguments.wheel = info.wheel; + arguments.nonClient = info.nonClient; + arguments.x = point.x - bounds.x1; + arguments.y = point.y - bounds.y1; RaiseMouseEvent(arguments, composition, eventReceiverEvent); } } - INativeWindowListener::HitTestResult GuiGraphicsHost::HitTest(Point location) + void GuiGraphicsHost::RecreateRenderTarget() { - Rect bounds = hostRecord.nativeWindow->GetBounds(); - Rect clientBounds = hostRecord.nativeWindow->GetClientBoundsInScreen(); - Point clientLocation(location.x + bounds.x1 - clientBounds.x1, location.y + bounds.y1 - clientBounds.y1); - GuiGraphicsComposition* hitComposition = windowComposition->FindComposition(clientLocation, false); + windowComposition->UpdateRelatedHostRecord(nullptr); + GetGuiGraphicsResourceManager()->RecreateRenderTarget(hostRecord.nativeWindow); + RefreshRelatedHostRecord(hostRecord.nativeWindow); + } + + INativeWindowListener::HitTestResult GuiGraphicsHost::HitTest(NativePoint location) + { + NativeRect bounds = hostRecord.nativeWindow->GetBounds(); + NativeRect clientBounds = hostRecord.nativeWindow->GetClientBoundsInScreen(); + NativePoint clientLocation(location.x + bounds.x1 - clientBounds.x1, location.y + bounds.y1 - clientBounds.y1); + auto point = hostRecord.nativeWindow->Convert(clientLocation); + GuiGraphicsComposition* hitComposition = windowComposition->FindComposition(point, false); while (hitComposition) { INativeWindowListener::HitTestResult result = hitComposition->GetAssociatedHitTestResult(); @@ -31725,11 +31774,11 @@ GuiGraphicsHost return INativeWindowListener::NoDecision; } - void GuiGraphicsHost::Moving(Rect& bounds, bool fixSizeOnly) + void GuiGraphicsHost::Moving(NativeRect& bounds, bool fixSizeOnly) { - Rect oldBounds = hostRecord.nativeWindow->GetBounds(); + NativeRect oldBounds = hostRecord.nativeWindow->GetBounds(); minSize = windowComposition->GetPreferredBounds().GetSize(); - Size minWindowSize = minSize + (oldBounds.GetSize() - hostRecord.nativeWindow->GetClientSize()); + NativeSize minWindowSize = hostRecord.nativeWindow->Convert(minSize) + (oldBounds.GetSize() - hostRecord.nativeWindow->GetClientSize()); if (bounds.Width() < minWindowSize.x) { if (fixSizeOnly) @@ -31770,7 +31819,7 @@ GuiGraphicsHost void GuiGraphicsHost::Moved() { - Size size = hostRecord.nativeWindow->GetClientSize(); + NativeSize size = hostRecord.nativeWindow->GetClientSize(); if (previousClientSize != size) { previousClientSize = size; @@ -31779,6 +31828,12 @@ GuiGraphicsHost } } + void GuiGraphicsHost::DpiChanged() + { + RecreateRenderTarget(); + needRender = true; + } + void GuiGraphicsHost::Paint() { if (!supressPaint) @@ -31858,7 +31913,8 @@ GuiGraphicsHost { CompositionList newCompositions; { - GuiGraphicsComposition* composition = windowComposition->FindComposition(Point(info.x, info.y), true); + auto point = hostRecord.nativeWindow->Convert(NativePoint(info.x, info.y)); + GuiGraphicsComposition* composition = windowComposition->FindComposition(point, true); while (composition) { newCompositions.Insert(0, composition); @@ -32061,7 +32117,7 @@ GuiGraphicsHost GetCurrentController()->CallbackService()->InstallListener(this); previousClientSize = _nativeWindow->GetClientSize(); minSize = windowComposition->GetPreferredBounds().GetSize(); - _nativeWindow->SetCaretPoint(caretPoint); + _nativeWindow->SetCaretPoint(_nativeWindow->Convert(caretPoint)); needRender = true; } @@ -32111,9 +32167,7 @@ GuiGraphicsHost break; case RenderTargetFailure::LostDevice: { - windowComposition->UpdateRelatedHostRecord(nullptr); - GetGuiGraphicsResourceManager()->RecreateRenderTarget(hostRecord.nativeWindow); - RefreshRelatedHostRecord(hostRecord.nativeWindow); + RecreateRenderTarget(); needRender = true; } break; @@ -32222,7 +32276,7 @@ GuiGraphicsHost caretPoint = value; if (hostRecord.nativeWindow) { - hostRecord.nativeWindow->SetCaretPoint(caretPoint); + hostRecord.nativeWindow->SetCaretPoint(hostRecord.nativeWindow->Convert(caretPoint)); } } @@ -32968,12 +33022,12 @@ namespace vl INativeWindowListener ***********************************************************************/ - INativeWindowListener::HitTestResult INativeWindowListener::HitTest(Point location) + INativeWindowListener::HitTestResult INativeWindowListener::HitTest(NativePoint location) { return INativeWindowListener::NoDecision; } - void INativeWindowListener::Moving(Rect& bounds, bool fixSizeOnly) + void INativeWindowListener::Moving(NativeRect& bounds, bool fixSizeOnly) { } @@ -32981,6 +33035,10 @@ INativeWindowListener { } + void INativeWindowListener::DpiChanged() + { + } + void INativeWindowListener::Enabled() { } @@ -33109,23 +33167,23 @@ INativeWindowListener INativeControllerListener ***********************************************************************/ - void INativeControllerListener::LeftButtonDown(Point position) + void INativeControllerListener::LeftButtonDown(NativePoint position) { } - void INativeControllerListener::LeftButtonUp(Point position) + void INativeControllerListener::LeftButtonUp(NativePoint position) { } - void INativeControllerListener::RightButtonDown(Point position) + void INativeControllerListener::RightButtonDown(NativePoint position) { } - void INativeControllerListener::RightButtonUp(Point position) + void INativeControllerListener::RightButtonUp(NativePoint position) { } - void INativeControllerListener::MouseMoving(Point position) + void INativeControllerListener::MouseMoving(NativePoint position) { } diff --git a/Import/GacUI.h b/Import/GacUI.h index af7e0716..1291653d 100644 --- a/Import/GacUI.h +++ b/Import/GacUI.h @@ -158,6 +158,47 @@ GridPos bool operator>=(const GridPos& value)const {return Compare(value)>=0;} }; +/*********************************************************************** +Coordinate +***********************************************************************/ + + /// + /// Represents a position in the local window coordinate space, which is DPI awared. + /// + using GuiCoordinate = vint; + + /// + /// Represents a position in the global screen coordinate space. + /// + struct NativeCoordinate + { + vint value; + + NativeCoordinate() :value(0) {} + NativeCoordinate(vint _value) :value(_value) {} + NativeCoordinate(const NativeCoordinate& _value) = default; + NativeCoordinate(NativeCoordinate&& _value) = default; + NativeCoordinate& operator=(const NativeCoordinate& _value) = default; + NativeCoordinate& operator=(NativeCoordinate&& _value) = default; + + inline bool operator==(NativeCoordinate c)const { return value == c.value; }; + inline bool operator!=(NativeCoordinate c)const { return value != c.value; }; + inline bool operator<(NativeCoordinate c)const { return value < c.value; }; + inline bool operator<=(NativeCoordinate c)const { return value <= c.value; }; + inline bool operator>(NativeCoordinate c)const { return value > c.value; }; + inline bool operator>=(NativeCoordinate c)const { return value >= c.value; }; + + inline NativeCoordinate operator+(NativeCoordinate c)const { return value + c.value; }; + inline NativeCoordinate operator-(NativeCoordinate c)const { return value - c.value; }; + inline NativeCoordinate operator*(NativeCoordinate c)const { return value * c.value; }; + inline NativeCoordinate operator/(NativeCoordinate c)const { return value / c.value; }; + + inline NativeCoordinate& operator+=(NativeCoordinate c) { value += c.value; return *this; }; + inline NativeCoordinate& operator-=(NativeCoordinate c) { value -= c.value; return *this; }; + inline NativeCoordinate& operator*=(NativeCoordinate c) { value *= c.value; return *this; }; + inline NativeCoordinate& operator/=(NativeCoordinate c) { value /= c.value; return *this; }; + }; + /*********************************************************************** Point ***********************************************************************/ @@ -165,38 +206,43 @@ Point /// /// Represents a position in a two dimensions space. /// - struct Point + /// Type of the coordinate. + template + struct Point_ { /// /// Position in x dimension. /// - vint x; + T x; /// /// Position in y dimension. /// - vint y; + T y; - Point() - :x(0) ,y(0) + Point_() + :x(0), y(0) { } - Point(vint _x, vint _y) - :x(_x) ,y(_y) + Point_(T _x, T _y) + :x(_x), y(_y) { } - bool operator==(Point point)const + bool operator==(Point_ point)const { - return x==point.x && y==point.y; + return x == point.x && y == point.y; } - bool operator!=(Point point)const + bool operator!=(Point_ point)const { - return x!=point.x || y!=point.y; + return x != point.x || y != point.y; } }; + using Point = Point_; + using NativePoint = Point_; + /*********************************************************************** Size ***********************************************************************/ @@ -204,38 +250,43 @@ Size /// /// Represents a size in a two dimensions space. /// - struct Size + /// Type of the coordinate. + template + struct Size_ { /// /// Size in x dimension. /// - vint x; + T x; /// /// Size in y dimension. /// - vint y; + T y; - Size() - :x(0) ,y(0) + Size_() + :x(0), y(0) { } - Size(vint _x, vint _y) - :x(_x) ,y(_y) + Size_(T _x, T _y) + :x(_x), y(_y) { } - bool operator==(Size size)const + bool operator==(Size_ size)const { - return x==size.x && y==size.y; + return x == size.x && y == size.y; } - bool operator!=(Size size)const + bool operator!=(Size_ size)const { - return x!=size.x || y!=size.y; + return x != size.x || y != size.y; } }; + using Size = Size_; + using NativeSize = Size_; + /*********************************************************************** Rectangle ***********************************************************************/ @@ -243,202 +294,219 @@ Rectangle /// /// Represents a bounds in a two dimensions space. /// - struct Rect + /// Type of the coordinate. + template + struct Rect_ { /// /// Left. /// - vint x1; + T x1; /// /// Top. /// - vint y1; + T y1; /// /// Left + Width. /// - vint x2; + T x2; /// /// Top + Height. /// - vint y2; + T y2; - Rect() + Rect_() :x1(0), y1(0), x2(0), y2(0) { } - Rect(vint _x1, vint _y1, vint _x2, vint _y2) + Rect_(T _x1, T _y1, T _x2, T _y2) :x1(_x1), y1(_y1), x2(_x2), y2(_y2) { } - Rect(Point p, Size s) - :x1(p.x), y1(p.y), x2(p.x+s.x), y2(p.y+s.y) + Rect_(Point_ p, Size_ s) + :x1(p.x), y1(p.y), x2(p.x + s.x), y2(p.y + s.y) { } - bool operator==(Rect rect)const + bool operator==(Rect_ rect)const { - return x1==rect.x1 && y1==rect.y1 && x2==rect.x2 && y2==rect.y2; + return x1 == rect.x1 && y1 == rect.y1 && x2 == rect.x2 && y2 == rect.y2; } - bool operator!=(Rect rect)const + bool operator!=(Rect_ rect)const { - return x1!=rect.x1 || y1!=rect.y1 || x2!=rect.x2 || y2!=rect.y2; + return x1 != rect.x1 || y1 != rect.y1 || x2 != rect.x2 || y2 != rect.y2; } - Point LeftTop()const + Point_ LeftTop()const { - return Point(x1, y1); + return Point_(x1, y1); } - Point RightBottom()const + Point_ RightBottom()const { - return Point(x2, y2); + return Point_(x2, y2); } - Size GetSize()const + Size_ GetSize()const { - return Size(x2-x1, y2-y1); + return Size_(x2 - x1, y2 - y1); } - vint Left()const + T Left()const { return x1; } - vint Right()const + T Right()const { return x2; } - vint Width()const + T Width()const { - return x2-x1; + return x2 - x1; } - vint Top()const + T Top()const { return y1; } - vint Bottom()const + T Bottom()const { return y2; } - vint Height()const + T Height()const { - return y2-y1; + return y2 - y1; } - void Expand(vint x, vint y) + void Expand(T x, T y) { - x1-=x; - y1-=y; - x2+=x; - y2+=y; + x1 -= x; + y1 -= y; + x2 += x; + y2 += y; } - void Expand(Size s) + void Expand(Size_ s) { - x1-=s.x; - y1-=s.y; - x2+=s.x; - y2+=s.y; + x1 -= s.x; + y1 -= s.y; + x2 += s.x; + y2 += s.y; } - void Move(vint x, vint y) + void Move(T x, T y) { - x1+=x; - y1+=y; - x2+=x; - y2+=y; + x1 += x; + y1 += y; + x2 += x; + y2 += y; } - void Move(Size s) + void Move(Size_ s) { - x1+=s.x; - y1+=s.y; - x2+=s.x; - y2+=s.y; + x1 += s.x; + y1 += s.y; + x2 += s.x; + y2 += s.y; } - bool Contains(Point p) + bool Contains(Point_ p) { - return x1<=p.x && p.x; + using NativeRect = Rect_; + /*********************************************************************** 2D operations ***********************************************************************/ - inline Point operator+(Point p, Size s) + template + inline Point_ operator+(Point_ p, Size_ s) { - return Point(p.x+s.x, p.y+s.y); + return Point_(p.x + s.x, p.y + s.y); } - inline Point operator+(Size s, Point p) + template + inline Point_ operator+(Size_ s, Point_ p) { - return Point(p.x+s.x, p.y+s.y); + return Point_(p.x + s.x, p.y + s.y); } - inline Point operator-(Point p, Size s) + template + inline Point_ operator-(Point_ p, Size_ s) { - return Point(p.x-s.x, p.y-s.y); + return Point_(p.x - s.x, p.y - s.y); } - inline Size operator-(Point p1, Point p2) + template + inline Size_ operator-(Point_ p1, Point_ p2) { - return Size(p1.x-p2.x, p1.y-p2.y); + return Size_(p1.x - p2.x, p1.y - p2.y); } - inline Size operator+(Size s1, Size s2) + template + inline Size_ operator+(Size_ s1, Size_ s2) { - return Size(s1.x+s2.x, s1.y+s2.y); + return Size_(s1.x + s2.x, s1.y + s2.y); } - inline Size operator-(Size s1, Size s2) + template + inline Size_ operator-(Size_ s1, Size_ s2) { - return Size(s1.x-s2.x, s1.y-s2.y); + return Size_(s1.x - s2.x, s1.y - s2.y); } - inline Size operator*(Size s, vint i) + template + inline Size_ operator*(Size_ s, vint i) { - return Size(s.x*i, s.y*i); + return Size_(s.x*i, s.y*i); } - inline Size operator/(Size s, vint i) + template + inline Size_ operator/(Size_ s, vint i) { - return Size(s.x/i, s.y/i); + return Size_(s.x / i, s.y / i); } - inline Point operator+=(Point& s1, Size s2) + template + inline Point_ operator+=(Point_& s1, Size_ s2) { - s1.x+=s2.x; - s1.y+=s2.y; + s1.x += s2.x; + s1.y += s2.y; return s1; } - inline Point operator-=(Point& s1, Size s2) + template + inline Point_ operator-=(Point_& s1, Size_ s2) { - s1.x-=s2.x; - s1.y-=s2.y; + s1.x -= s2.x; + s1.y -= s2.y; return s1; } - inline Size operator+=(Size& s1, Size s2) + template + inline Size_ operator+=(Size_& s1, Size_ s2) { - s1.x+=s2.x; - s1.y+=s2.y; + s1.x += s2.x; + s1.y += s2.y; return s1; } - inline Size operator-=(Size& s1, Size s2) + template + inline Size_ operator-=(Size_& s1, Size_ s2) { - s1.x-=s2.x; - s1.y-=s2.y; + s1.x -= s2.x; + s1.y -= s2.y; return s1; } @@ -538,46 +606,51 @@ Margin /// /// Represents a margin in a two dimensions space. /// - struct Margin + /// Type of the coordinate. + template + struct Margin_ { /// /// The left margin. /// - vint left; + T left; /// /// The top margin. /// - vint top; + T top; /// /// The right margin. /// - vint right; + T right; /// /// The bottom margin. /// - vint bottom; + T bottom; - Margin() + Margin_() :left(0), top(0), right(0), bottom(0) { } - Margin(vint _left, vint _top, vint _right, vint _bottom) + Margin_(T _left, T _top, T _right, T _bottom) :left(_left), top(_top), right(_right), bottom(_bottom) { } - bool operator==(Margin margin)const + bool operator==(Margin_ margin)const { return left==margin.left && top==margin.top && right==margin.right && bottom==margin.bottom; } - bool operator!=(Margin margin)const + bool operator!=(Margin_ margin)const { return left!=margin.left || top!=margin.top || right!=margin.right || bottom!=margin.bottom; } }; + using Margin = Margin_; + using NativeMargin = Margin_; + /*********************************************************************** Resources ***********************************************************************/ @@ -1302,19 +1375,19 @@ System Object /// /// Represents a screen. /// - class INativeScreen : public virtual IDescriptable, Description + class INativeScreen : public virtual IDescriptable, public Description { public: /// /// Get the bounds of the screen. /// /// The bounds of the screen. - virtual Rect GetBounds()=0; + virtual NativeRect GetBounds()=0; /// /// Get the bounds of the screen client area. /// /// The bounds of the screen client area. - virtual Rect GetClientBounds()=0; + virtual NativeRect GetClientBounds()=0; /// /// Get the name of the screen. /// @@ -1325,12 +1398,20 @@ System Object /// /// Returns true if the screen is a primary screen. virtual bool IsPrimary()=0; + /// + /// Get the scaling for the screen's horizontal edge. For example, in Windows when you have a 96 DPI, this function returns 1.0. + /// + virtual double GetScalingX() = 0; + /// + /// Get the scaling for the screen's vertical edge. For example, in Windows when you have a 96 DPI, this function returns 1.0. + /// + virtual double GetScalingY() = 0; }; /// /// Represents a cursor. /// - class INativeCursor : public virtual IDescriptable, Description + class INativeCursor : public virtual IDescriptable, public Description { public: /// @@ -1581,30 +1662,66 @@ Native Window { public: /// + /// Convert point from native coordinate to GUI coordinate. + /// + /// The converted result. + /// The coordinate to convert. + virtual Point Convert(NativePoint value) = 0; + /// + /// Convert point from GUI coordinate to native coordinate. + /// + /// The converted result. + /// The coordinate to convert. + virtual NativePoint Convert(Point value) = 0; + /// + /// Convert size from native coordinate to GUI coordinate. + /// + /// The converted result. + /// The coordinate to convert. + virtual Size Convert(NativeSize value) = 0; + /// + /// Convert size from GUI coordinate to native coordinate. + /// + /// The converted result. + /// The coordinate to convert. + virtual NativeSize Convert(Size value) = 0; + /// + /// Convert margin from native coordinate to GUI coordinate. + /// + /// The converted result. + /// The coordinate to convert. + virtual Margin Convert(NativeMargin value) = 0; + /// + /// Convert margin from GUI coordinate to native coordinate. + /// + /// The converted result. + /// The coordinate to convert. + virtual NativeMargin Convert(Margin value) = 0; + /// Get the bounds of the window. /// /// The bounds of the window. - virtual Rect GetBounds()=0; + virtual NativeRect GetBounds()=0; /// /// Set the bounds of the window. /// /// The bounds of the window. - virtual void SetBounds(const Rect& bounds)=0; + virtual void SetBounds(const NativeRect& bounds)=0; /// /// Get the client size of the window. /// /// The client size of the window. - virtual Size GetClientSize()=0; + virtual NativeSize GetClientSize()=0; /// /// Set the client size of the window. /// /// The client size of the window. - virtual void SetClientSize(Size size)=0; + virtual void SetClientSize(NativeSize size)=0; /// /// Get the client bounds in screen space. /// /// The client bounds in screen space. - virtual Rect GetClientBoundsInScreen()=0; + virtual NativeRect GetClientBoundsInScreen()=0; /// /// Get the title of the window. A title will be displayed as a name of this window. @@ -1630,12 +1747,12 @@ Native Window /// Get the caret point of the window. When an input method editor is opened, the input text box will be located to the caret point. /// /// The caret point of the window. - virtual Point GetCaretPoint()=0; + virtual NativePoint GetCaretPoint()=0; /// /// Set the caret point of the window. When an input method editor is opened, the input text box will be located to the caret point. /// /// The caret point of the window. - virtual void SetCaretPoint(Point point)=0; + virtual void SetCaretPoint(NativePoint point)=0; /// /// Get the parent window. A parent window doesn't contain a child window. It always displayed below the child windows. When a parent window is minimized or restored, so as its child windows. @@ -1675,7 +1792,7 @@ Native Window /// Get the amount of the border. The window template may need this value to calculate where to put the client area. /// /// Returns the amount of the border. - virtual Margin GetCustomFramePadding() = 0; + virtual NativeMargin GetCustomFramePadding() = 0; /// Window size state. enum WindowSizeState @@ -1909,7 +2026,9 @@ Native Window /// /// Mouse message information. /// - struct NativeWindowMouseInfo + /// Type of the coordinate. + template + struct WindowMouseInfo_ { /// True if the control button is pressed. bool ctrl; @@ -1922,14 +2041,17 @@ Native Window /// True if the right mouse button is pressed. bool right; /// The mouse position of x dimension. - vint x; + T x; /// The mouse position of y dimension. - vint y; + T y; /// The delta of the wheel. vint wheel; /// True if the mouse is in the non-client area. bool nonClient; }; + + using WindowMouseInfo = WindowMouseInfo_; + using NativeWindowMouseInfo = WindowMouseInfo_; /// /// Key message information. @@ -1949,6 +2071,8 @@ Native Window /// True if this repeated event is generated because a key is holding down. bool autoRepeatKeyDown; }; + + using WindowKeyInfo = NativeWindowKeyInfo; /// /// Character message information. @@ -1966,6 +2090,8 @@ Native Window /// True if the capslock button is pressed. bool capslock; }; + + using WindowCharInfo = NativeWindowCharInfo; /// /// Represents a message listener to an . @@ -2015,18 +2141,22 @@ Native Window /// /// Returns the hit test result. If "NoDecision" is returned, the native window provider should call the OS window layer to do the hit test. /// The location to do the hit test. This location is in the window space (not the client space). - virtual HitTestResult HitTest(Point location); + virtual HitTestResult HitTest(NativePoint location); /// /// Called when the window is moving. /// /// The bounds. Message handler can change the bounds. /// True if the message raise only want the message handler to change the size. - virtual void Moving(Rect& bounds, bool fixSizeOnly); + virtual void Moving(NativeRect& bounds, bool fixSizeOnly); /// /// Called when the window is moved. /// virtual void Moved(); /// + /// Called when the dpi associated with this window is changed. + /// + virtual void DpiChanged(); + /// /// Called when the window is enabled. /// virtual void Enabled(); @@ -2404,7 +2534,7 @@ Native Window Services /// /// The window that under a specified position in screen space. /// The specified position in screen space. - virtual INativeWindow* GetWindow(Point location) = 0; + virtual INativeWindow* GetWindow(NativePoint location) = 0; /// /// Make the specified window a main window, show that window, and wait until the windows is closed. /// @@ -2769,27 +2899,27 @@ Native Window Controller /// Called when the left mouse button is pressed. To receive or not receive this message, use or . /// /// The mouse position in the screen space. - virtual void LeftButtonDown(Point position); + virtual void LeftButtonDown(NativePoint position); /// /// Called when the left mouse button is released. To receive or not receive this message, use or /// /// The mouse position in the screen space. - virtual void LeftButtonUp(Point position); + virtual void LeftButtonUp(NativePoint position); /// /// Called when the right mouse button is pressed. To receive or not receive this message, use or /// /// The mouse position in the screen space. - virtual void RightButtonDown(Point position); + virtual void RightButtonDown(NativePoint position); /// /// Called when the right mouse button is released. To receive or not receive this message, use or /// /// The mouse position in the screen space. - virtual void RightButtonUp(Point position); + virtual void RightButtonUp(NativePoint position); /// /// Called when the mouse is moving. To receive or not receive this message, use or /// /// The mouse position in the screen space. - virtual void MouseMoving(Point position); + virtual void MouseMoving(NativePoint position); /// /// Called when the global timer message raised. To receive or not receive this message, use or /// @@ -3093,7 +3223,7 @@ Predefined Events }; /// Keyboard event arguments. - struct GuiKeyEventArgs : public GuiEventArgs, public NativeWindowKeyInfo, public Description + struct GuiKeyEventArgs : public GuiEventArgs, public WindowKeyInfo, public Description { /// Create an event arguments with and set to null. GuiKeyEventArgs() @@ -3109,7 +3239,7 @@ Predefined Events }; /// Char input event arguments. - struct GuiCharEventArgs : public GuiEventArgs, public NativeWindowCharInfo, public Description + struct GuiCharEventArgs : public GuiEventArgs, public WindowCharInfo, public Description { /// Create an event arguments with and set to null. GuiCharEventArgs() @@ -3125,7 +3255,7 @@ Predefined Events }; /// Mouse event arguments. - struct GuiMouseEventArgs : public GuiEventArgs, public NativeWindowMouseInfo, public Description + struct GuiMouseEventArgs : public GuiEventArgs, public WindowMouseInfo, public Description { /// Create an event arguments with and set to null. GuiMouseEventArgs() @@ -8716,12 +8846,17 @@ Control Host /// Set the client size of the window. /// The client size of the window. void SetClientSize(Size value); - /// Get the bounds of the window in screen space. - /// The bounds of the window. - Rect GetBounds(); - /// Set the bounds of the window in screen space. - /// The bounds of the window. - void SetBounds(Rect value); + /// Get the location of the window in screen space. + /// The location of the window. + NativePoint GetLocation(); + /// Set the location of the window in screen space. + /// The location of the window. + void SetLocation(NativePoint value); + /// Set the location in screen space and the client size of the window. + /// The location of the window. + /// The client size of the window. + void SetBounds(NativePoint location, Size size); + GuiControlHost* GetRelatedControlHost()override; const WString& GetText()override; void SetText(const WString& value)override; @@ -8783,8 +8918,10 @@ Window bool hasTitleBar = true; Ptr icon; + void UpdateCustomFramePadding(INativeWindow* window, templates::GuiWindowTemplate* ct); void SyncNativeWindowProperties(); void Moved()override; + void DpiChanged()override; void OnNativeWindowChanged()override; void OnVisualStatusChanged()override; virtual void MouseClickedOnOtherWindow(GuiWindow* window); @@ -8906,7 +9043,7 @@ Window protected: union PopupInfo { - struct _s1 { Point location; INativeScreen* screen; }; + struct _s1 { NativePoint location; INativeScreen* screen; }; struct _s2 { GuiControl* control; INativeWindow* controlWindow; Rect bounds; bool preferredTopBottomSide; }; struct _s3 { GuiControl* control; INativeWindow* controlWindow; Point location; }; struct _s4 { GuiControl* control; INativeWindow* controlWindow; bool preferredTopBottomSide; }; @@ -8928,12 +9065,12 @@ Window void PopupClosed(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - static bool IsClippedByScreen(Size size, Point location, INativeScreen* screen); - static Point CalculatePopupPosition(Size size, Point location, INativeScreen* screen); - static Point CalculatePopupPosition(Size size, GuiControl* control, INativeWindow* controlWindow, Rect bounds, bool preferredTopBottomSide); - static Point CalculatePopupPosition(Size size, GuiControl* control, INativeWindow* controlWindow, Point location); - static Point CalculatePopupPosition(Size size, GuiControl* control, INativeWindow* controlWindow, bool preferredTopBottomSide); - static Point CalculatePopupPosition(Size size, vint popupType, const PopupInfo& popupInfo); + static bool IsClippedByScreen(NativeSize size, NativePoint location, INativeScreen* screen); + static NativePoint CalculatePopupPosition(NativeSize windowSize, NativePoint location, INativeScreen* screen); + static NativePoint CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, Rect bounds, bool preferredTopBottomSide); + static NativePoint CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, Point location); + static NativePoint CalculatePopupPosition(NativeSize windowSize, GuiControl* control, INativeWindow* controlWindow, bool preferredTopBottomSide); + static NativePoint CalculatePopupPosition(NativeSize windowSize, vint popupType, const PopupInfo& popupInfo); void ShowPopupInternal(); public: @@ -8949,7 +9086,7 @@ Window /// Show the popup window with the left-top position set to a specified value. The position of the popup window will be adjusted to make it totally inside the screen if possible. /// The specified left-top position. /// The expected screen. If you don't want to specify any screen, don't set this parameter. - void ShowPopup(Point location, INativeScreen* screen = 0); + void ShowPopup(NativePoint location, INativeScreen* screen = 0); /// Show the popup window with the bounds set to a specified control-relative value. The position of the popup window will be adjusted to make it totally inside the screen if possible. /// The control that owns this popup temporary. And the location is relative to this control. /// The specified bounds. @@ -9036,10 +9173,10 @@ Application friend class Ptr; private: void InvokeClipboardNotify(compositions::GuiGraphicsComposition* composition, compositions::GuiEventArgs& arguments); - void LeftButtonDown(Point position)override; - void LeftButtonUp(Point position)override; - void RightButtonDown(Point position)override; - void RightButtonUp(Point position)override; + void LeftButtonDown(NativePoint position)override; + void LeftButtonUp(NativePoint position)override; + void RightButtonDown(NativePoint position)override; + void RightButtonUp(NativePoint position)override; void ClipboardUpdated()override; protected: Locale locale; @@ -9060,7 +9197,7 @@ Application void UnregisterWindow(GuiWindow* window); void RegisterPopupOpened(GuiPopup* popup); void RegisterPopupClosed(GuiPopup* popup); - void OnMouseDown(Point location); + void OnMouseDown(NativePoint location); void TooltipMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); void TooltipMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); public: @@ -9086,7 +9223,7 @@ Application /// Get the instance that the mouse cursor are directly in. /// The instance that the mouse cursor are directly in. /// The mouse cursor. - GuiWindow* GetWindow(Point location); + GuiWindow* GetWindow(NativePoint location); /// Show a tooltip. /// The control that owns this tooltip temporary. /// The control as the tooltip content. This control is not owned by the tooltip. User should manually release this control if no longer needed (usually when the application exit). @@ -11084,7 +11221,7 @@ Host controls::GuiControlHost* controlHost = nullptr; GuiWindowComposition* windowComposition = nullptr; GuiGraphicsComposition* focusedComposition = nullptr; - Size previousClientSize; + NativeSize previousClientSize; Size minSize; Point caretPoint; vuint64_t lastCaretTime = 0; @@ -11101,11 +11238,13 @@ Host void OnKeyInput(const NativeWindowKeyInfo& info, GuiGraphicsComposition* composition, GuiKeyEvent GuiGraphicsEventReceiver::* eventReceiverEvent); void RaiseMouseEvent(GuiMouseEventArgs& arguments, GuiGraphicsComposition* composition, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent); void OnMouseInput(const NativeWindowMouseInfo& info, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent); + void RecreateRenderTarget(); private: - INativeWindowListener::HitTestResult HitTest(Point location)override; - void Moving(Rect& bounds, bool fixSizeOnly)override; + INativeWindowListener::HitTestResult HitTest(NativePoint location)override; + void Moving(NativeRect& bounds, bool fixSizeOnly)override; void Moved()override; + void DpiChanged()override; void Paint()override; void LeftButtonDown(const NativeWindowMouseInfo& info)override; diff --git a/Import/GacUIReflection.cpp b/Import/GacUIReflection.cpp index 6c2d5650..5833ab26 100644 --- a/Import/GacUIReflection.cpp +++ b/Import/GacUIReflection.cpp @@ -243,16 +243,30 @@ Type Declaration STRUCT_MEMBER(column) END_STRUCT_MEMBER(GridPos) + BEGIN_STRUCT_MEMBER(NativeCoordinate) + STRUCT_MEMBER(value) + END_STRUCT_MEMBER(NativeCoordinate) + BEGIN_STRUCT_MEMBER(Point) STRUCT_MEMBER(x) STRUCT_MEMBER(y) END_STRUCT_MEMBER(Point) + BEGIN_STRUCT_MEMBER(NativePoint) + STRUCT_MEMBER(x) + STRUCT_MEMBER(y) + END_STRUCT_MEMBER(NativePoint) + BEGIN_STRUCT_MEMBER(Size) STRUCT_MEMBER(x) STRUCT_MEMBER(y) END_STRUCT_MEMBER(Size) + BEGIN_STRUCT_MEMBER(NativeSize) + STRUCT_MEMBER(x) + STRUCT_MEMBER(y) + END_STRUCT_MEMBER(NativeSize) + BEGIN_STRUCT_MEMBER(Rect) STRUCT_MEMBER(x1) STRUCT_MEMBER(y1) @@ -260,6 +274,13 @@ Type Declaration STRUCT_MEMBER(y2) END_STRUCT_MEMBER(Rect) + BEGIN_STRUCT_MEMBER(NativeRect) + STRUCT_MEMBER(x1) + STRUCT_MEMBER(y1) + STRUCT_MEMBER(x2) + STRUCT_MEMBER(y2) + END_STRUCT_MEMBER(NativeRect) + BEGIN_STRUCT_MEMBER(Margin) STRUCT_MEMBER(left) STRUCT_MEMBER(top) @@ -267,6 +288,13 @@ Type Declaration STRUCT_MEMBER(bottom) END_STRUCT_MEMBER(Margin) + BEGIN_STRUCT_MEMBER(NativeMargin) + STRUCT_MEMBER(left) + STRUCT_MEMBER(top) + STRUCT_MEMBER(right) + STRUCT_MEMBER(bottom) + END_STRUCT_MEMBER(NativeMargin) + BEGIN_STRUCT_MEMBER(FontProperties) STRUCT_MEMBER(fontFamily) STRUCT_MEMBER(size) @@ -412,6 +440,8 @@ Type Declaration CLASS_MEMBER_PROPERTY_READONLY_FAST(Bounds); CLASS_MEMBER_PROPERTY_READONLY_FAST(ClientBounds); CLASS_MEMBER_PROPERTY_READONLY_FAST(Name); + CLASS_MEMBER_PROPERTY_READONLY_FAST(ScalingX); + CLASS_MEMBER_PROPERTY_READONLY_FAST(ScalingY); CLASS_MEMBER_METHOD(IsPrimary, NO_PARAMETER) END_INTERFACE_MEMBER(INativeScreen) @@ -2224,7 +2254,7 @@ Type Declaration (Class) CLASS_MEMBER_PROPERTY_FAST(EnabledActivate) CLASS_MEMBER_PROPERTY_FAST(TopMost) CLASS_MEMBER_PROPERTY_FAST(ClientSize) - CLASS_MEMBER_PROPERTY_FAST(Bounds) + CLASS_MEMBER_PROPERTY_FAST(Location) CLASS_MEMBER_PROPERTY_FAST(ShortcutKeyManager) CLASS_MEMBER_PROPERTY_READONLY_FAST(RelatedScreen) @@ -2234,6 +2264,7 @@ Type Declaration (Class) CLASS_MEMBER_METHOD(SetFocused, NO_PARAMETER) CLASS_MEMBER_METHOD(GetActivated, NO_PARAMETER) CLASS_MEMBER_METHOD(SetActivated, NO_PARAMETER) + CLASS_MEMBER_METHOD(SetBounds, {L"location" _ L"size"}) CLASS_MEMBER_METHOD(Show, NO_PARAMETER) CLASS_MEMBER_METHOD(ShowDeactivated, NO_PARAMETER) CLASS_MEMBER_METHOD(ShowRestored, NO_PARAMETER) @@ -2269,7 +2300,7 @@ Type Declaration (Class) CLASS_MEMBER_BASE(GuiWindow) CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE(GuiPopup) - CLASS_MEMBER_METHOD_OVERLOAD(ShowPopup, {L"location" _ L"screen"}, void(GuiPopup::*)(Point _ INativeScreen*)) + CLASS_MEMBER_METHOD_OVERLOAD(ShowPopup, {L"location" _ L"screen"}, void(GuiPopup::*)(NativePoint _ INativeScreen*)) CLASS_MEMBER_METHOD_OVERLOAD(ShowPopup, {L"control" _ L"bounds" _ L"preferredTopBottomSide"}, void(GuiPopup::*)(GuiControl* _ Rect _ bool)) CLASS_MEMBER_METHOD_OVERLOAD(ShowPopup, {L"control" _ L"location"}, void(GuiPopup::*)(GuiControl* _ Point)) CLASS_MEMBER_METHOD_OVERLOAD(ShowPopup, {L"control" _ L"preferredTopBottomSide"}, void(GuiPopup::*)(GuiControl* _ bool)) diff --git a/Import/GacUIReflection.h b/Import/GacUIReflection.h index 999fac4b..1f77c1d6 100644 --- a/Import/GacUIReflection.h +++ b/Import/GacUIReflection.h @@ -102,10 +102,15 @@ Type List (Basic) F(presentation::AxisDirection)\ F(presentation::TextPos)\ F(presentation::GridPos)\ + F(presentation::NativeCoordinate)\ F(presentation::Point)\ + F(presentation::NativePoint)\ F(presentation::Size)\ + F(presentation::NativeSize)\ F(presentation::Rect)\ + F(presentation::NativeRect)\ F(presentation::Margin)\ + F(presentation::NativeMargin)\ F(presentation::FontProperties)\ F(presentation::VKEY)\ F(presentation::GlobalStringKey)\ diff --git a/Import/GacUIWindows.cpp b/Import/GacUIWindows.cpp index c21e47b8..fc35a923 100644 --- a/Import/GacUIWindows.cpp +++ b/Import/GacUIWindows.cpp @@ -3269,13 +3269,13 @@ WindowsDirect2DRenderTarget Rect GetClipper()override { - if(clippers.Count()==0) + if (clippers.Count() == 0) { - return Rect(Point(0, 0), window->GetClientSize()); + return Rect(Point(0, 0), window->Convert(window->GetClientSize())); } else { - return clippers[clippers.Count()-1]; + return clippers[clippers.Count() - 1]; } } @@ -7532,13 +7532,13 @@ WindowsGDIRenderTarget Rect GetClipper()override { - if(clippers.Count()==0) + if (clippers.Count() == 0) { - return Rect(Point(0, 0), window->GetClientSize()); + return Rect(Point(0, 0), window->Convert(window->GetClientSize())); } else { - return clippers[clippers.Count()-1]; + return clippers[clippers.Count() - 1]; } } @@ -7926,6 +7926,144 @@ void RendererMainGDI() SetGuiGraphicsResourceManager(0); } +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\WINNATIVEDPIAWARENESS.CPP +***********************************************************************/ + +#pragma comment(lib, "Shcore.lib") + +namespace vl +{ + namespace presentation + { + namespace windows + { + void InitDpiAwareness(bool dpiAware) + { + { + HMODULE moduleHandle = LoadLibrary(L"user32"); + bool available = GetProcAddress(moduleHandle, "SetProcessDpiAwarenessContext") != NULL; + FreeLibrary(moduleHandle); + if (available) + { + SetProcessDpiAwarenessContext(dpiAware ? DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: DPI_AWARENESS_CONTEXT_UNAWARE); + return; + } + } + { + HMODULE moduleHandle = LoadLibrary(L"Shcore"); + bool available = GetProcAddress(moduleHandle, "SetProcessDpiAwareness") != NULL; + FreeLibrary(moduleHandle); + if (available) + { + SetProcessDpiAwareness(dpiAware ? PROCESS_PER_MONITOR_DPI_AWARE : PROCESS_DPI_UNAWARE); + return; + } + } + } + + void DpiAwared_GetDpiForMonitor(HMONITOR monitor, UINT* x, UINT* y) + { + static bool initialized = false; + static bool available_GetDpiForMonitor = false; + if (!initialized) + { + initialized = true; + HMODULE moduleHandle = LoadLibrary(L"Shcore"); + available_GetDpiForMonitor = GetProcAddress(moduleHandle, "GetDpiForMonitor") != NULL; + FreeLibrary(moduleHandle); + } + + if (!available_GetDpiForMonitor) + { + *x = 96; + *y = 96; + } + + if (GetDpiForMonitor(monitor, MDT_DEFAULT, x, y) != S_OK) + { + *x = 96; + *y = 96; + } + } + + void DpiAwared_GetDpiForWindow(HWND handle, UINT* x, UINT* y) + { + static bool initialized = false; + static bool available_GetDpiForWindow = false; + if (!initialized) + { + initialized = true; + HMODULE moduleHandle = LoadLibrary(L"user32"); + available_GetDpiForWindow = GetProcAddress(moduleHandle, "GetDpiForWindow") != NULL; + FreeLibrary(moduleHandle); + } + + if (available_GetDpiForWindow) + { + *x = *y = GetDpiForWindow(handle); + } + else + { + HMONITOR monitor = MonitorFromWindow(handle, MONITOR_DEFAULTTONULL); + if (monitor == NULL) + { + *x = *y = 96; + } + else + { + DpiAwared_GetDpiForMonitor(monitor, x, y); + } + } + } + + void DpiAwared_AdjustWindowRect(LPRECT rect, HWND handle, UINT dpi) + { + static bool initialized = false; + static bool available_AdjustWindowRectExForDpi = false; + if (!initialized) + { + initialized = true; + HMODULE moduleHandle = LoadLibrary(L"user32"); + available_AdjustWindowRectExForDpi = GetProcAddress(moduleHandle, "AdjustWindowRectExForDpi") != NULL; + FreeLibrary(moduleHandle); + } + + if (available_AdjustWindowRectExForDpi) + { + AdjustWindowRectExForDpi(rect, (DWORD)GetWindowLongPtr(handle, GWL_STYLE), FALSE, (DWORD)GetWindowLongPtr(handle, GWL_EXSTYLE), dpi); + } + else + { + AdjustWindowRect(rect, (DWORD)GetWindowLongPtr(handle, GWL_STYLE), FALSE); + } + } + + int DpiAwared_GetSystemMetrics(int index, UINT dpi) + { + static bool initialized = false; + static bool available_GetSystemMetricsForDpi = false; + if (!initialized) + { + initialized = true; + HMODULE moduleHandle = LoadLibrary(L"user32"); + available_GetSystemMetricsForDpi = GetProcAddress(moduleHandle, "GetSystemMetricsForDpi") != NULL; + FreeLibrary(moduleHandle); + } + + if (available_GetSystemMetricsForDpi) + { + return GetSystemMetricsForDpi(index, dpi); + } + else + { + return GetSystemMetrics(index); + } + } + } + } +} + /*********************************************************************** .\NATIVEWINDOW\WINDOWS\WINNATIVEWINDOW.CPP ***********************************************************************/ @@ -7948,7 +8086,7 @@ namespace vl HICON CreateWindowDefaultIcon(vint size = 0) { if (!defaultIconResourceName) return NULL; - return (HICON)LoadImage(GetModuleHandle(NULL), defaultIconResourceName, IMAGE_ICON, size, size, (size ? 0 : LR_DEFAULTSIZE) | LR_SHARED); + return (HICON)LoadImage(GetModuleHandle(NULL), defaultIconResourceName, IMAGE_ICON, (int)size, (int)size, (size ? 0 : LR_DEFAULTSIZE) | LR_SHARED); } void SetWindowDefaultIcon(UINT resourceId) @@ -8116,9 +8254,9 @@ WindowsForm info.right = WinIsKeyPressing(VKEY::_RBUTTON); POINTS point = MAKEPOINTS(lParam); - Point offset = GetClientBoundsInScreen().LeftTop(); - info.x = point.x - offset.x; - info.y = point.y - offset.y; + NativePoint offset = GetClientBoundsInScreen().LeftTop(); + info.x = point.x - offset.x.value; + info.y = point.y - offset.y.value; } else { @@ -8132,9 +8270,9 @@ WindowsForm if (wheelMessage) { - Point offset = GetClientBoundsInScreen().LeftTop(); - info.x = point.x - offset.x; - info.y = point.y - offset.y; + NativePoint offset = GetClientBoundsInScreen().LeftTop(); + info.x = point.x - offset.x.value; + info.y = point.y - offset.y.value; } else { @@ -8184,8 +8322,8 @@ WindowsForm HIMC imc = ImmGetContext(handle); COMPOSITIONFORM cf; cf.dwStyle = CFS_POINT; - cf.ptCurrentPos.x = (int)caretPoint.x; - cf.ptCurrentPos.y = (int)caretPoint.y; + cf.ptCurrentPos.x = (int)caretPoint.x.value; + cf.ptCurrentPos.y = (int)caretPoint.y.value; ImmSetCompositionWindow(imc, &cf); ImmReleaseContext(handle, imc); } @@ -8214,20 +8352,20 @@ WindowsForm case WM_MOVING:case WM_SIZING: { LPRECT rawBounds=(LPRECT)lParam; - Rect bounds(rawBounds->left, rawBounds->top, rawBounds->right, rawBounds->bottom); + NativeRect bounds(rawBounds->left, rawBounds->top, rawBounds->right, rawBounds->bottom); for(vint i=0;iMoving(bounds, false); } - if( rawBounds->left!=bounds.Left() - || rawBounds->top!=bounds.Top() - || rawBounds->right!=bounds.Right() - || rawBounds->bottom!=bounds.Bottom()) + if( rawBounds->left!=bounds.Left().value + || rawBounds->top!=bounds.Top().value + || rawBounds->right!=bounds.Right().value + || rawBounds->bottom!=bounds.Bottom().value) { - rawBounds->left=(int)bounds.Left(); - rawBounds->top=(int)bounds.Top(); - rawBounds->right=(int)bounds.Right(); - rawBounds->bottom=(int)bounds.Bottom(); + rawBounds->left=(int)bounds.Left().value; + rawBounds->top=(int)bounds.Top().value; + rawBounds->right=(int)bounds.Right().value; + rawBounds->bottom=(int)bounds.Bottom().value; result=TRUE; } } @@ -8240,6 +8378,19 @@ WindowsForm } } break; + case WM_DPICHANGED: + { + dpiX = LOWORD(wParam); + dpiY = HIWORD(wParam); + UpdateDpiAwaredFields(false); + auto newRect = (RECT*)lParam; + MoveWindow(handle, newRect->left, newRect->top, (newRect->right - newRect->left), (newRect->bottom - newRect->top), FALSE); + for (vint i = 0; i < listeners.Count(); i++) + { + listeners[i]->DpiChanged(); + } + } + break; // ************************************** state case WM_ENABLE: { @@ -8582,12 +8733,12 @@ WindowsForm case WM_NCHITTEST: { POINTS location=MAKEPOINTS(lParam); - Point windowLocation=GetBounds().LeftTop(); - location.x-=(SHORT)windowLocation.x; - location.y-=(SHORT)windowLocation.y; + NativePoint windowLocation=GetBounds().LeftTop(); + location.x-=(SHORT)windowLocation.x.value; + location.y-=(SHORT)windowLocation.y.value; for(vint i=0;iHitTest(Point(location.x, location.y))) + switch(listeners[i]->HitTest(NativePoint(location.x, location.y))) { case INativeWindowListener::BorderNoSizing: result=HTBORDER; @@ -8712,7 +8863,7 @@ WindowsForm POINTS location = MAKEPOINTS(lParam); for(vint i=0;iHitTest(Point(location.x, location.y))) + switch(listeners[i]->HitTest(NativePoint(location.x, location.y))) { case INativeWindowListener::ButtonMinimum: ShowMinimized(); @@ -8742,7 +8893,7 @@ WindowsForm HWND handle; WString title; WindowsCursor* cursor = nullptr; - Point caretPoint; + NativePoint caretPoint; WindowsForm* parentWindow = nullptr; bool alwaysPassFocusToParent = false; List listeners; @@ -8754,20 +8905,30 @@ WindowsForm List> messageHandlers; bool supressingAlt = false; Ptr flagDisposed = new bool(false); - Margin customFramePadding; + NativeMargin customFramePadding; Ptr defaultIcon; Ptr replacementIcon; HICON replacementHIcon = NULL; + UINT dpiX = 0; + UINT dpiY = 0; + void UpdateDpiAwaredFields(bool refreshDpiXY) + { + if (refreshDpiXY) + { + DpiAwared_GetDpiForWindow(handle, &dpiX, &dpiY); + } + auto padding = (vint)(DpiAwared_GetSystemMetrics(SM_CXSIZEFRAME, dpiX) + DpiAwared_GetSystemMetrics(SM_CXPADDEDBORDER, dpiX)); + customFramePadding = NativeMargin(padding, padding, padding, padding); + } public: WindowsForm(HWND parent, WString className, HINSTANCE hInstance) { DWORD exStyle = WS_EX_APPWINDOW | WS_EX_CONTROLPARENT; DWORD style = WS_BORDER | WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; - handle=CreateWindowEx(exStyle, className.Buffer(), L"", style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, parent, NULL, hInstance, NULL); + handle = CreateWindowEx(exStyle, className.Buffer(), L"", style, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, parent, NULL, hInstance, NULL); - auto padding = (vint)(GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)); - customFramePadding = Margin(padding, padding, padding, padding); + UpdateDpiAwaredFields(true); } ~WindowsForm() @@ -8857,38 +9018,78 @@ WindowsForm return true; } - Rect GetBounds() + Point Convert(NativePoint value)override + { + return Point((vint)value.x.value * 96 / dpiX, (vint)value.y.value * 96 / dpiY); + } + + NativePoint Convert(Point value)override + { + return NativePoint(value.x * dpiX / 96, value.y * dpiY / 96); + } + + Size Convert(NativeSize value)override + { + return Size((vint)value.x.value * 96 / dpiX, (vint)value.y.value * 96 / dpiY); + } + + NativeSize Convert(Size value)override + { + return NativeSize(value.x * dpiX / 96, value.y * dpiY / 96); + } + + Margin Convert(NativeMargin value)override + { + return Margin( + (vint)value.left.value * 96 / dpiX, + (vint)value.top.value * 96 / dpiY, + (vint)value.right.value * 96 / dpiX, + (vint)value.bottom.value * 96 / dpiY + ); + } + + NativeMargin Convert(Margin value)override + { + return NativeMargin( + (vint)value.left * dpiX / 96, + (vint)value.top * dpiY / 96, + (vint)value.right * dpiX / 96, + (vint)value.bottom * dpiY / 96 + ); + } + + NativeRect GetBounds()override { RECT rect; GetWindowRect(handle, &rect); - return Rect(rect.left, rect.top, rect.right, rect.bottom); + return NativeRect(rect.left, rect.top, rect.right, rect.bottom); } - void SetBounds(const Rect& bounds) + void SetBounds(const NativeRect& bounds)override { - Rect newBounds=bounds; + NativeRect newBounds=bounds; for(vint i=0;iMoving(newBounds, true); } - MoveWindow(handle, (int)newBounds.Left(), (int)newBounds.Top(), (int)newBounds.Width(), (int)newBounds.Height(), FALSE); + MoveWindow(handle, (int)newBounds.Left().value, (int)newBounds.Top().value, (int)newBounds.Width().value, (int)newBounds.Height().value, FALSE); } - Size GetClientSize() + NativeSize GetClientSize()override { return GetClientBoundsInScreen().GetSize(); } - void SetClientSize(Size size) + void SetClientSize(NativeSize size)override { - RECT required={0,0,(int)size.x,(int)size.y}; + RECT required={0,0,(int)size.x.value,(int)size.y.value }; RECT bounds; GetWindowRect(handle, &bounds); - AdjustWindowRect(&required, (DWORD)GetWindowLongPtr(handle, GWL_STYLE), FALSE); - SetBounds(Rect(Point(bounds.left, bounds.top), Size(required.right-required.left, required.bottom-required.top))); + DpiAwared_AdjustWindowRect(&required, handle, dpiX); + SetBounds(NativeRect(NativePoint(bounds.left, bounds.top), NativeSize(required.right-required.left, required.bottom-required.top))); } - Rect GetClientBoundsInScreen() + NativeRect GetClientBoundsInScreen()override { if(customFrameMode) { @@ -8899,13 +9100,13 @@ WindowsForm RECT required={0,0,0,0}; RECT bounds; GetWindowRect(handle, &bounds); - AdjustWindowRect(&required, (DWORD)GetWindowLongPtr(handle, GWL_STYLE), FALSE); - return Rect( - Point( + DpiAwared_AdjustWindowRect(&required, handle, dpiX); + return NativeRect( + NativePoint( (bounds.left-required.left), (bounds.top-required.top) ), - Size( + NativeSize( (bounds.right-bounds.left)-(required.right-required.left), (bounds.bottom-bounds.top)-(required.bottom-required.top) ) @@ -8913,23 +9114,23 @@ WindowsForm } } - WString GetTitle() + WString GetTitle()override { return title; } - void SetTitle(WString _title) + void SetTitle(WString _title)override { title=_title; SetWindowText(handle, title.Buffer()); } - INativeCursor* GetWindowCursor() + INativeCursor* GetWindowCursor()override { return cursor; } - void SetWindowCursor(INativeCursor* _cursor) + void SetWindowCursor(INativeCursor* _cursor)override { WindowsCursor* newCursor=dynamic_cast(_cursor); if(newCursor && cursor!=newCursor) @@ -8942,23 +9143,23 @@ WindowsForm } } - Point GetCaretPoint() + NativePoint GetCaretPoint()override { return caretPoint; } - void SetCaretPoint(Point point) + void SetCaretPoint(NativePoint point)override { caretPoint=point; UpdateCompositionForContent(); } - INativeWindow* GetParent() + INativeWindow* GetParent()override { return parentWindow; } - void SetParent(INativeWindow* parent) + void SetParent(INativeWindow* parent)override { parentWindow=dynamic_cast(parent); if(parentWindow) @@ -8971,32 +9172,32 @@ WindowsForm } } - bool GetAlwaysPassFocusToParent() + bool GetAlwaysPassFocusToParent()override { return alwaysPassFocusToParent; } - void SetAlwaysPassFocusToParent(bool value) + void SetAlwaysPassFocusToParent(bool value)override { alwaysPassFocusToParent=value; } - void EnableCustomFrameMode() + void EnableCustomFrameMode()override { customFrameMode=true; } - void DisableCustomFrameMode() + void DisableCustomFrameMode()override { customFrameMode=false; } - bool IsCustomFrameModeEnabled() + bool IsCustomFrameModeEnabled()override { return customFrameMode; } - Margin GetCustomFramePadding() + NativeMargin GetCustomFramePadding()override { if (GetSizeBox() || GetTitleBar()) { @@ -9004,11 +9205,11 @@ WindowsForm } else { - return Margin(0, 0, 0, 0); + return NativeMargin(0, 0, 0, 0); } } - Ptr GetIcon() + Ptr GetIcon()override { if (replacementIcon && replacementIcon->GetImage()) { @@ -9071,7 +9272,7 @@ WindowsForm return -1; } - void SetIcon(Ptr icon) + void SetIcon(Ptr icon)override { replacementIcon = icon; HICON newReplacementHIcon = NULL; @@ -9190,7 +9391,7 @@ WindowsForm replacementHIcon = newReplacementHIcon; } - WindowSizeState GetSizeState() + WindowSizeState GetSizeState()override { if(IsIconic(handle)) { @@ -9206,33 +9407,33 @@ WindowsForm } } - void Show() + void Show()override { ShowWindow(handle, SW_SHOWNORMAL); } - void ShowDeactivated() + void ShowDeactivated()override { ShowWindow(handle, SW_SHOWNOACTIVATE); SetWindowPos(handle,HWND_TOP,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); } - void ShowRestored() + void ShowRestored()override { ShowWindow(handle, SW_RESTORE); } - void ShowMaximized() + void ShowMaximized()override { ShowWindow(handle, SW_SHOWMAXIMIZED); } - void ShowMinimized() + void ShowMinimized()override { ShowWindow(handle, SW_SHOWMINIMIZED); } - void Hide(bool closeWindow) + void Hide(bool closeWindow)override { if (closeWindow) { @@ -9244,164 +9445,164 @@ WindowsForm } } - bool IsVisible() + bool IsVisible()override { return IsWindowVisible(handle)!=0; } - void Enable() + void Enable()override { EnableWindow(handle, TRUE); } - void Disable() + void Disable()override { EnableWindow(handle, FALSE); } - bool IsEnabled() + bool IsEnabled()override { return IsWindowEnabled(handle)!=0; } - void SetFocus() + void SetFocus()override { ::SetFocus(handle); } - bool IsFocused() + bool IsFocused()override { return GetFocus()==handle; } - void SetActivate() + void SetActivate()override { SetActiveWindow(handle); } - bool IsActivated() + bool IsActivated()override { return GetActiveWindow()==handle; } - void ShowInTaskBar() + void ShowInTaskBar()override { SetExStyle(WS_EX_APPWINDOW, true); } - void HideInTaskBar() + void HideInTaskBar()override { SetExStyle(WS_EX_APPWINDOW, false); } - bool IsAppearedInTaskBar() + bool IsAppearedInTaskBar()override { return GetExStyle(WS_EX_APPWINDOW); } - void EnableActivate() + void EnableActivate()override { SetExStyle(WS_EX_NOACTIVATE, false); } - void DisableActivate() + void DisableActivate()override { SetExStyle(WS_EX_NOACTIVATE, true); } - bool IsEnabledActivate() + bool IsEnabledActivate()override { return !GetExStyle(WS_EX_NOACTIVATE); } - bool RequireCapture() + bool RequireCapture()override { SetCapture(handle); return true; } - bool ReleaseCapture() + bool ReleaseCapture()override { ::ReleaseCapture(); return true; } - bool IsCapturing() + bool IsCapturing()override { return GetCapture()==handle; } - bool GetMaximizedBox() + bool GetMaximizedBox()override { return GetStyle(WS_MAXIMIZEBOX); } - void SetMaximizedBox(bool visible) + void SetMaximizedBox(bool visible)override { SetStyle(WS_MAXIMIZEBOX, visible); } - bool GetMinimizedBox() + bool GetMinimizedBox()override { return GetStyle(WS_MINIMIZEBOX); } - void SetMinimizedBox(bool visible) + void SetMinimizedBox(bool visible)override { SetStyle(WS_MINIMIZEBOX, visible); } - bool GetBorder() + bool GetBorder()override { return GetStyle(WS_BORDER); } - void SetBorder(bool visible) + void SetBorder(bool visible)override { SetStyle(WS_BORDER, visible); } - bool GetSizeBox() + bool GetSizeBox()override { return GetStyle(WS_SIZEBOX); } - void SetSizeBox(bool visible) + void SetSizeBox(bool visible)override { SetStyle(WS_SIZEBOX, visible); } - bool GetIconVisible() + bool GetIconVisible()override { return GetStyle(WS_SYSMENU); } - void SetIconVisible(bool visible) + void SetIconVisible(bool visible)override { SetStyle(WS_SYSMENU, visible); } - bool GetTitleBar() + bool GetTitleBar()override { return GetStyle(WS_CAPTION); } - void SetTitleBar(bool visible) + void SetTitleBar(bool visible)override { SetStyle(WS_CAPTION, visible); } - bool GetTopMost() + bool GetTopMost()override { return GetExStyle(WS_EX_TOPMOST); } - void SetTopMost(bool topmost) + void SetTopMost(bool topmost)override { SetWindowPos(handle, (topmost ? HWND_TOPMOST : HWND_NOTOPMOST), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED); } - void SupressAlt() + void SupressAlt()override { if (!supressingAlt) { @@ -9411,7 +9612,7 @@ WindowsForm } } - bool InstallListener(INativeWindowListener* listener) + bool InstallListener(INativeWindowListener* listener)override { if(listeners.Contains(listener)) { @@ -9424,7 +9625,7 @@ WindowsForm } } - bool UninstallListener(INativeWindowListener* listener) + bool UninstallListener(INativeWindowListener* listener)override { if(listeners.Contains(listener)) { @@ -9437,7 +9638,7 @@ WindowsForm } } - void RedrawContent() + void RedrawContent()override { if(graphicsHandler) { @@ -9594,11 +9795,11 @@ WindowsController } } - INativeWindow* GetWindow(Point location)override + INativeWindow* GetWindow(NativePoint location)override { POINT p; - p.x=(int)location.x; - p.y=(int)location.y; + p.x=(int)location.x.value; + p.y=(int)location.y.value; HWND handle=WindowFromPoint(p); vint index=windows.Keys().IndexOf(handle); if(index==-1) @@ -9667,7 +9868,7 @@ WindowsController //======================================================================= - void InvokeMouseHook(WPARAM message, Point location) + void InvokeMouseHook(WPARAM message, NativePoint location) { callbackService.InvokeMouseHook(message, location); } @@ -9725,7 +9926,7 @@ Windows Procedure if(controller) { MSLLHOOKSTRUCT* mouseHookStruct=(MSLLHOOKSTRUCT*)lParam; - Point location(mouseHookStruct->pt.x, mouseHookStruct->pt.y); + NativePoint location(mouseHookStruct->pt.x, mouseHookStruct->pt.y); controller->InvokeMouseHook(wParam, location); } return CallNextHookEx(NULL,nCode,wParam,lParam); @@ -9793,12 +9994,12 @@ Windows Platform Native Controller /*********************************************************************** .\NATIVEWINDOW\WINDOWS\DIRECT2D\WINDIRECT2DAPPLICATION.CPP ***********************************************************************/ + #pragma comment(lib, "d2d1.lib") #pragma comment(lib, "dxguid.lib") #pragma comment(lib, "dwrite.lib") #pragma comment(lib, "d3d11.lib") - namespace vl { namespace presentation @@ -9821,7 +10022,7 @@ WindowListener bool rendering = false; bool movedWhileRendering = false; - virtual void RebuildCanvas(Size size) = 0; + virtual void RebuildCanvas(NativeSize size) = 0; public: Direct2DWindowsNativeWindowListener(INativeWindow* _window, ID2D1Factory* _d2dFactory) :window(_window) @@ -9829,7 +10030,7 @@ WindowListener { } - void Moved() + void Moved()override { if (rendering) { @@ -9876,38 +10077,43 @@ WindowListener 1.0 { protected: ComPtr d2dRenderTarget; - Size previousSize; + NativeSize previousSize; - void RebuildCanvas(Size size)override + void RebuildCanvas(NativeSize size)override { if (size.x <= 1) size.x = 1; if (size.y <= 1) size.y = 1; - if(!d2dRenderTarget) + if (!d2dRenderTarget) { - ID2D1HwndRenderTarget* renderTarget=0; - IWindowsForm* form=GetWindowsForm(window); - D2D1_RENDER_TARGET_PROPERTIES tp=D2D1::RenderTargetProperties(); - tp.dpiX=96; - tp.dpiY=96; - HRESULT hr=d2dFactory->CreateHwndRenderTarget( + ID2D1HwndRenderTarget* renderTarget = 0; + IWindowsForm* form = GetWindowsForm(window); + D2D1_RENDER_TARGET_PROPERTIES tp = D2D1::RenderTargetProperties(); + { + UINT dpiX = 0; + UINT dpiY = 0; + DpiAwared_GetDpiForWindow(form->GetWindowHandle(), &dpiX, &dpiY); + tp.dpiX = (FLOAT)dpiX; + tp.dpiY = (FLOAT)dpiY; + } + HRESULT hr = d2dFactory->CreateHwndRenderTarget( tp, D2D1::HwndRenderTargetProperties( form->GetWindowHandle(), - D2D1::SizeU((int)size.x, (int)size.y) - ), + D2D1::SizeU((int)size.x.value, (int)size.y.value) + ), &renderTarget - ); - if(!FAILED(hr)) + ); + if (!FAILED(hr)) { - d2dRenderTarget=renderTarget; + d2dRenderTarget = renderTarget; d2dRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); } } - else if(previousSize!=size) + else if (previousSize != size) { - d2dRenderTarget->Resize(D2D1::SizeU((int)size.x, (int)size.y)); + d2dRenderTarget->Resize(D2D1::SizeU((int)size.x.value, (int)size.y.value)); } - previousSize=size; + previousSize = size; } public: Direct2DWindowsNativeWindowListener_1_0(INativeWindow* _window, ID2D1Factory* _d2dFactory) @@ -9947,7 +10153,7 @@ WindowListener 1.1 ComPtr dxgiDevice; ComPtr dxgiSwapChain; ComPtr d2dDeviceContext; - Size previousSize; + NativeSize previousSize; ComPtr GetDXGIDevice() { @@ -10037,7 +10243,7 @@ WindowListener 1.1 return d2dBitmap; } - void RebuildCanvas(Size size)override + void RebuildCanvas(NativeSize size)override { if (size.x <= 1) size.x = 1; if (size.y <= 1) size.y = 1; @@ -10057,7 +10263,13 @@ WindowListener 1.1 d2dDeviceContext = CreateDeviceContext(dxgiDevice.Obj()); auto d2dBitmap = CreateBitmap(dxgiSwapChain.Obj(), d2dDeviceContext.Obj()); d2dDeviceContext->SetTarget(d2dBitmap.Obj()); - d2dDeviceContext->SetDpi(96, 96); + IWindowsForm* form = GetWindowsForm(window); + { + UINT dpiX = 0; + UINT dpiY = 0; + DpiAwared_GetDpiForWindow(form->GetWindowHandle(), &dpiX, &dpiY); + d2dDeviceContext->SetDpi((FLOAT)dpiX, (FLOAT)dpiY); + } } else if(previousSize!=size) { @@ -10405,6 +10617,7 @@ int WinMainDirect2D(HINSTANCE hInstance, void(*RendererMain)()) int SetupWindowsDirect2DRenderer() { + InitDpiAwareness(true); CoInitializeEx(NULL, COINIT_MULTITHREADED); HINSTANCE hInstance=(HINSTANCE)GetModuleHandle(NULL); WinDirect2DApplicationDirect2DObjectProvider objectProvider; @@ -12385,31 +12598,32 @@ namespace vl } } - Size CalculateBufferSize() + NativeSize CalculateBufferSize() { - Size windowSize=window->GetClientSize(); - Size minBounds(windowSize.x*5/4, windowSize.y*5/4); - Size maxBounds(windowSize.x*3/2, windowSize.y*3/2); - Size currentSize=buffer?Size(buffer->GetWidth(), buffer->GetHeight()):Size(0, 0); - vint newWidth=DetermineBufferLength(windowSize.x, minBounds.x, maxBounds.x, currentSize.x); - vint newHeight=DetermineBufferLength(windowSize.y, minBounds.y, maxBounds.y, currentSize.y); - return Size(newWidth, newHeight); + NativeSize nativeWindowSize = window->GetClientSize(); + Size windowSize(nativeWindowSize.x.value, nativeWindowSize.y.value); + Size minBounds(windowSize.x * 5 / 4, windowSize.y * 5 / 4); + Size maxBounds(windowSize.x * 3 / 2, windowSize.y * 3 / 2); + Size currentSize = buffer ? Size(buffer->GetWidth(), buffer->GetHeight()) : Size(0, 0); + vint newWidth = DetermineBufferLength(windowSize.x, minBounds.x, maxBounds.x, currentSize.x); + vint newHeight = DetermineBufferLength(windowSize.y, minBounds.y, maxBounds.y, currentSize.y); + return NativeSize(newWidth, newHeight); } - void RebuildCanvas(Size size) + void RebuildCanvas(NativeSize size) { - if(size.x<256)size.x=256; - if(size.y<256)size.y=256; - if(buffer) + if (size.x < 256)size.x = 256; + if (size.y < 256)size.y = 256; + if (buffer) { - if(buffer->GetWidth()!=size.x || buffer->GetHeight()!=size.y) + if (buffer->GetWidth() != size.x.value || buffer->GetHeight() != size.y.value) { - buffer=0; + buffer = 0; } } - if(!buffer) + if (!buffer) { - buffer=new WinBitmap(size.x, size.y, WinBitmap::vbb32Bits, true); + buffer = new WinBitmap(size.x.value, size.y.value, WinBitmap::vbb32Bits, true); buffer->GetWinDC()->SetBackTransparent(true); } } @@ -12559,6 +12773,7 @@ int WinMainGDI(HINSTANCE hInstance, void(*RendererMain)()) int SetupWindowsGDIRenderer() { + InitDpiAwareness(false); CoInitializeEx(NULL, COINIT_MULTITHREADED); HINSTANCE hInstance=(HINSTANCE)GetModuleHandle(NULL); WinGDIApplicationGDIObjectProvider objectProvider; @@ -12819,7 +13034,7 @@ WindowsCallbackService } } - void WindowsCallbackService::InvokeMouseHook(WPARAM message, Point location) + void WindowsCallbackService::InvokeMouseHook(WPARAM message, NativePoint location) { switch(message) { @@ -14466,20 +14681,20 @@ WindowsScreen monitor=NULL; } - Rect WindowsScreen::GetBounds() + NativeRect WindowsScreen::GetBounds() { MONITORINFOEX info; info.cbSize=sizeof(MONITORINFOEX); GetMonitorInfo(monitor, &info); - return Rect(info.rcMonitor.left, info.rcMonitor.top, info.rcMonitor.right, info.rcMonitor.bottom); + return NativeRect(info.rcMonitor.left, info.rcMonitor.top, info.rcMonitor.right, info.rcMonitor.bottom); } - Rect WindowsScreen::GetClientBounds() + NativeRect WindowsScreen::GetClientBounds() { MONITORINFOEX info; info.cbSize=sizeof(MONITORINFOEX); GetMonitorInfo(monitor, &info); - return Rect(info.rcWork.left, info.rcWork.top, info.rcWork.right, info.rcWork.bottom); + return NativeRect(info.rcWork.left, info.rcWork.top, info.rcWork.right, info.rcWork.bottom); } WString WindowsScreen::GetName() @@ -14502,6 +14717,20 @@ WindowsScreen return info.dwFlags==MONITORINFOF_PRIMARY; } + double WindowsScreen::GetScalingX() + { + UINT x = 0, y = 0; + DpiAwared_GetDpiForMonitor(monitor, &x, &y); + return x / 96.0; + } + + double WindowsScreen::GetScalingY() + { + UINT x = 0, y = 0; + DpiAwared_GetDpiForMonitor(monitor, &x, &y); + return y / 96.0; + } + /*********************************************************************** WindowsScreenService ***********************************************************************/ diff --git a/Import/GacUIWindows.h b/Import/GacUIWindows.h index d6bd99be..5744fb81 100644 --- a/Import/GacUIWindows.h +++ b/Import/GacUIWindows.h @@ -500,6 +500,44 @@ namespace vl #endif +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\WINNATIVEDPIAWARENESS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Windows Implementation + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_WINDOWS_WINNATIVEDPIAWARENESS +#define VCZH_PRESENTATION_WINDOWS_WINNATIVEDPIAWARENESS + +#include +#include + +namespace vl +{ + namespace presentation + { + namespace windows + { +/*********************************************************************** +DPI Awareness Functions +***********************************************************************/ + + extern void InitDpiAwareness(bool dpiAware); + extern void DpiAwared_GetDpiForMonitor(HMONITOR monitor, UINT* x, UINT* y); + extern void DpiAwared_GetDpiForWindow(HWND handle, UINT* x, UINT* y); + extern void DpiAwared_AdjustWindowRect(LPRECT rect, HWND handle, UINT dpi); + extern int DpiAwared_GetSystemMetrics(int index, UINT dpi); + } + } +} + +#endif + /*********************************************************************** .\NATIVEWINDOW\WINDOWS\GDI\WINGDI.H ***********************************************************************/ @@ -564,7 +602,6 @@ Comments: #ifndef VCZH_PRESENTATION_WINDOWS_GDI_WINGDI #define VCZH_PRESENTATION_WINDOWS_GDI_WINGDI -#include namespace vl { @@ -2140,13 +2177,16 @@ namespace vl friend class WindowsScreenService; protected: HMONITOR monitor; + public: WindowsScreen(); - Rect GetBounds()override; - Rect GetClientBounds()override; + NativeRect GetBounds()override; + NativeRect GetClientBounds()override; WString GetName()override; bool IsPrimary()override; + double GetScalingX()override; + double GetScalingY()override; }; class WindowsScreenService : public Object, public INativeScreenService @@ -2155,12 +2195,13 @@ namespace vl protected: collections::List> screens; HandleRetriver handleRetriver; + public: struct MonitorEnumProcData { - WindowsScreenService* screenService; - vint currentScreen; + WindowsScreenService* screenService; + vint currentScreen; }; WindowsScreenService(HandleRetriver _handleRetriver); @@ -2209,7 +2250,7 @@ namespace vl bool InstallListener(INativeControllerListener* listener)override; bool UninstallListener(INativeControllerListener* listener)override; - void InvokeMouseHook(WPARAM message, Point location); + void InvokeMouseHook(WPARAM message, NativePoint location); void InvokeGlobalTimer(); void InvokeClipboardUpdated(); void InvokeNativeWindowCreated(INativeWindow* window); diff --git a/Import/Vlpp.h b/Import/Vlpp.h index 46ec6cd6..927cddb9 100644 --- a/Import/Vlpp.h +++ b/Import/Vlpp.h @@ -7015,7 +7015,7 @@ Tokenizer /// The internal state. InternalState GetInternalState(); /// Restore the colorizer to a internal state. - /// The internal state. + /// The internal state. void SetInternalState(InternalState state); /// Step forward by one character. /// The input character. diff --git a/Import/VlppWorkflowCompiler.cpp b/Import/VlppWorkflowCompiler.cpp index 6e9c9b12..10cbe536 100644 --- a/Import/VlppWorkflowCompiler.cpp +++ b/Import/VlppWorkflowCompiler.cpp @@ -24159,6 +24159,8 @@ namespace vl typedef WfInstruction Ins; #define INSTRUCTION(X) context.AddInstruction(node, X) +#define FILL_LABEL_TO_INS(LABEL, INS) context.assembly->instructions[LABEL].indexParameter = INS +#define FILL_LABEL_TO_CURRENT(LABEL) FILL_LABEL_TO_INS(LABEL, context.assembly->instructions.Count()) /*********************************************************************** GenerateTypeCastInstructions @@ -24168,6 +24170,17 @@ GenerateTypeCastInstructions { if (expectedType->GetTypeDescriptor() != GetTypeDescriptor()) { + vint fillElseIndex = -1; + vint fillEndIndex = -1; + + if (expectedType->GetDecorator() == ITypeInfo::Nullable) + { + INSTRUCTION(Ins::Duplicate(0)); + INSTRUCTION(Ins::LoadValue(Value())); + INSTRUCTION(Ins::CompareReference()); + fillElseIndex = INSTRUCTION(Ins::JumpIf(-1)); + } + if (strongCast) { switch (expectedType->GetDecorator()) @@ -24202,6 +24215,14 @@ GenerateTypeCastInstructions break; } } + + if (fillElseIndex != -1) + { + fillEndIndex = INSTRUCTION(Ins::Jump(-1)); + FILL_LABEL_TO_CURRENT(fillElseIndex); + INSTRUCTION(Ins::LoadValue(Value())); + FILL_LABEL_TO_CURRENT(fillEndIndex); + } } } @@ -24236,7 +24257,7 @@ GetInstructionTypeArgument } /*********************************************************************** -GenerateTypeCastInstructions +GetInstructionTypeArgument ***********************************************************************/ runtime::WfInsType GetInstructionTypeArgument(Ptr expectedType) @@ -24373,6 +24394,8 @@ GenerateAssembly } #undef CALLBACK +#undef FILL_LABEL_TO_CURRENT +#undef FILL_LABEL_TO_INS #undef INSTRUCTION /*********************************************************************** @@ -24987,6 +25010,8 @@ namespace vl typedef WfInstruction Ins; #define INSTRUCTION(X) context.AddInstruction(node, X) +#define FILL_LABEL_TO_INS(LABEL, INS) context.assembly->instructions[LABEL].indexParameter = INS +#define FILL_LABEL_TO_CURRENT(LABEL) FILL_LABEL_TO_INS(LABEL, context.assembly->instructions.Count()) /*********************************************************************** GenerateInstructions(Expression) @@ -25461,10 +25486,10 @@ GenerateInstructions(Expression) INSTRUCTION(Ins::UninstallTry(1)); vint finishInstruction = INSTRUCTION(Ins::Jump(-1)); - context.assembly->instructions[trapInstruction].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(trapInstruction); GenerateExpressionInstructions(context, node->second, result.type); - context.assembly->instructions[finishInstruction].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(finishInstruction); } else { @@ -25617,9 +25642,9 @@ GenerateInstructions(Expression) vint fillTrueIndex = INSTRUCTION(Ins::JumpIf(-1)); GenerateExpressionInstructions(context, node->falseBranch, result.type); vint fillEndIndex = INSTRUCTION(Ins::Jump(-1)); - context.assembly->instructions[fillTrueIndex].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(fillTrueIndex); GenerateExpressionInstructions(context, node->trueBranch, result.type); - context.assembly->instructions[fillEndIndex].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(fillEndIndex); } void Visit(WfRangeExpression* node)override @@ -26123,6 +26148,8 @@ GenerateInstructions(Expression) } }; +#undef FILL_LABEL_TO_CURRENT +#undef FILL_LABEL_TO_INS #undef INSTRUCTION Ptr GenerateExpressionInstructions(WfCodegenContext& context, Ptr expression, Ptr expectedType) @@ -26433,6 +26460,8 @@ namespace vl typedef WfInstruction Ins; #define INSTRUCTION(X) context.AddInstruction(node, X) +#define FILL_LABEL_TO_INS(LABEL, INS) context.assembly->instructions[LABEL].indexParameter = INS +#define FILL_LABEL_TO_CURRENT(LABEL) FILL_LABEL_TO_INS(LABEL, context.assembly->instructions.Count()) #define EXIT_CODE(X) context.AddExitInstruction(node, X) /*********************************************************************** @@ -26577,13 +26606,13 @@ GenerateInstructions(Statement) INSTRUCTION(Ins::StoreLocalVar(variableIndex)); } vint fillEndIndex = INSTRUCTION(Ins::Jump(-1)); - context.assembly->instructions[fillElseIndex].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(fillElseIndex); if (node->falseBranch) { GenerateStatementInstructions(context, node->falseBranch); } - context.assembly->instructions[fillEndIndex].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(fillEndIndex); } void Visit(WfWhileStatement* node)override @@ -26604,11 +26633,11 @@ GenerateInstructions(Statement) FOREACH(vint, index, loopContext->continueInstructions) { - context.assembly->instructions[index].indexParameter = continueLabelIndex; + FILL_LABEL_TO_INS(index, continueLabelIndex); } FOREACH(vint, index, loopContext->breakInstructions) { - context.assembly->instructions[index].indexParameter = breakLabelIndex; + FILL_LABEL_TO_INS(index, breakLabelIndex); } context.functionContext->PopScopeContext(); } @@ -26655,7 +26684,7 @@ GenerateInstructions(Statement) void GenerateTrap(WfTryStatement* node, vint variableIndex, Pair trap) { - context.assembly->instructions[trap.key].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(trap.key); INSTRUCTION(Ins::LoadException()); INSTRUCTION(Ins::StoreLocalVar(variableIndex)); } @@ -26697,10 +26726,10 @@ GenerateInstructions(Statement) } // finally - context.assembly->instructions[trap1.value].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(trap1.value); if (trap2.value != -1) { - context.assembly->instructions[trap2.value].indexParameter = context.assembly->instructions.Count(); + FILL_LABEL_TO_CURRENT(trap2.value); } if (node->finallyStatement) { @@ -26726,7 +26755,7 @@ GenerateInstructions(Statement) vint breakLabelIndex = context.assembly->instructions.Count(); FOREACH(vint, index, blockContext->breakInstructions) { - context.assembly->instructions[index].indexParameter = breakLabelIndex; + FILL_LABEL_TO_INS(index, breakLabelIndex); } context.functionContext->PopScopeContext(); } @@ -26774,6 +26803,8 @@ GenerateInstructions(Statement) }; #undef EXIT_CODE +#undef FILL_LABEL_TO_CURRENT +#undef FILL_LABEL_TO_INS #undef INSTRUCTION void GenerateStatementInstructions(WfCodegenContext& context, Ptr statement) diff --git a/Import/VlppWorkflowRuntime.h b/Import/VlppWorkflowRuntime.h index 0f21767b..e7410ad5 100644 --- a/Import/VlppWorkflowRuntime.h +++ b/Import/VlppWorkflowRuntime.h @@ -63,7 +63,7 @@ Instruction TestType, // flag, typeDescriptor : Value -> ; GetType, // : Value -> ; Jump, // label : () -> () ; - JumpIf, // label : () -> () ; + JumpIf, // label : -> () ; Invoke, // function, count : Value-1, ..., Value-n -> Value ; InvokeWithContext, // function, count : Value-1, ..., Value-n -> Value ; GetProperty, // IPropertyInfo* : Value-this -> Value ; diff --git a/Tools/CppMerge.exe b/Tools/CppMerge.exe index ec3feda0..c4713320 100644 Binary files a/Tools/CppMerge.exe and b/Tools/CppMerge.exe differ diff --git a/Tools/GacGen32.exe b/Tools/GacGen32.exe index e0245219..a210e6d1 100644 Binary files a/Tools/GacGen32.exe and b/Tools/GacGen32.exe differ diff --git a/Tools/GacGen64.exe b/Tools/GacGen64.exe index 86924701..2c0a99a8 100644 Binary files a/Tools/GacGen64.exe and b/Tools/GacGen64.exe differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 index dbb439ca..ad4deef6 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 and b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 index a78160d8..aef02ca5 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 and b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 differ