Is it possible to choose the default screen in a multi monitor configuration?

Hi all!

I’m working on a project that requires a fullscreen window to appear in a specific monitor.

My question is: Is it possible (via C++ or Blueprint) to detect how many monitors are being used and set a default monitor in which the program will appear when launched?

An example of what is pretended is, while using a triple-monitor configuration, making the application launch in fullscreen mode in the right monitor.

Thanks in advance for all the help :slight_smile:

In C++ you got this:

https://docs.unrealengine.com/latest/INT/API/Runtime/Core/GenericPlatform/FDisplayMetrics/index.html

First you call this to get the metrics:

FDisplayMetrics Display;
FDisplayMetrics::GetDisplayMetrics(Display);

And then you check how many moniters there is by checking MonitorInfo array size with Display.MonitorInfo.Num()

1 Like

As far as I can tell Unreal does not support this natively, but it would be platform specific.

On windows you should be able to use the info here:

https://www.microsoft.com/msj/0697/monitor/monitor.aspx

Essentially what you do is you enumerate all your monitors, find the one you want, and then move your application to there and maximize it.

edit:

Looking in WindowsWindow.cpp, you probably want to write a function very similar to GetFullScreenInfo that just enumerates the windows instead of using a rectangle and then gets the corresponding data from it, then use MoveWindowTo to move the window to there and MAximize to biggify it.

UE4 got huge set of platfrom specific function wrappers, specially made so it’s easy to make your game portable (well technily it was made to make engine portable :p):

https://docs.unrealengine.com/latest/INT/API/Runtime/Core/GenericPlatform/index.html

I was looking for something like that, but couldn’t figure out where EnumDisplayDevices was hooked up to something generic. The spot in your answer looks like that spot. :stuck_out_tongue:

Thanks for all the help. I found a really simple solution for this problem. Here’s the source code if anyone comes across the same situation :wink:

// Move window to the corresponding monitor
if (GEngine && GEngine->GameViewport) {
	
	int MonitorNumber = 1;
	FParse::Value(FCommandLine::Get(), L"monitor=", MonitorNumber);
	
	FDisplayMetrics Display;
	FDisplayMetrics::GetDisplayMetrics(Display);

	int8 MonitorIndex = MonitorNumber - 1;
	int32 CurrentMonitorWidth = Display.MonitorInfo[MonitorIndex].NativeWidth;
	
	float WidthPosition = (MonitorIndex)*Display.PrimaryDisplayWidth - CurrentMonitorWidth;

	float HeightPosition = 0.0f;

	FVector2D WindowPosition = FVector2D(WidthPosition, 0.f);
	GEngine->GameViewport->GetWindow()->MoveWindowTo(WindowPosition);
}

As you are creating your game to run on 3 monitors ??? You are using a Multiplayer scheme ???
Or this opening the windows as viewports ???

You could specify the schema that vc this using to open the windows?

Is there any way you can communicate this functionality to a blueprint user? I’m trying my best to understand this, and I get it for the most part - but I’ve only been able to teach myself blueprint and don’t know where to put this code, how to call it, or anything like that when it comes to building my came to run on a non-primary monitor.

Hello, I’m trying to use this code, but since unreal made some changes in c++, i getting this error when I compile:

error LNK2019: unresolved external symbol “__declspec(dllimport) public: static void __cdecl FDisplayMetrics::GetDisplayMetrics(struct FDisplayMetrics &)” (_imp?GetDisplayMetrics@FDisplayMetrics@@SAXAEAU1@@Z) referenced in function “protected: virtual void __cdecl UDisplaySettings::BeginPlay(void)” (?Beg
inPlay@UDisplaySettings@@MEAAXXZ)

I’ve already Include the “Engine.h” and “GenericApplication.h”, but still no success.
Can you help me? I can’t find a solution anywhere.

I think all the answers here are incomplete as they assume the following:

  • user has all monitors with the same resolution
  • monitors are aligned from left to right
  • runs only on windows (on linux apparently it does not work properly only in windowed mode)
  • destination monitor also has a native resolution larger or equal to the game resolution

The only information you need is from FMonitorInfo.WorkArea Left/Top.

FDisplayMetrics Display;
FDisplayMetrics::GetDisplayMetrics(Display);
    
// Start on the main display by default
int32 MonitorNumber = 0;
FParse::Value(FCommandLine::Get(), TEXT("monitor="), MonitorNumber);

// Get the correct monitor index
int32 MonitorIndex = INDEX_NONE;
if (MonitorNumber == 0)
{
    // Start monitor on the main screen
    for (int32 Index = 0; Index < DisplayMetrics.MonitorInfo.Num(); Index++)
    {
        if (DisplayMetrics.MonitorInfo[Index].bIsPrimary)
        {
            MonitorIndex = Index;
            break;
        }
    }
}
else
{
    // Normalize
    MonitorIndex = MonitorNumber - 1;
}
 
if (DisplayMetrics.MonitorInfo.IsValidIndex(MonitorIndex))
{
	const FMonitorInfo Monitor = DisplayMetrics.MonitorInfo[MonitorIndex];
    // check if UserSettings.ResolutionSizeX > Monitor.NativeWidth || UserSettings.ResolutionSizeY > Monitor.NativeHeight
    // if true then change your game resolution to Monitor.NativeWidth, Monitor.NativeHeight

    const int32 WindowPosX = Monitor.WorkArea.Left;
	const int32 WindowPosY = Monitor.WorkArea.Top;
    const FVector2D Position(static_cast<float>(WindowPosX), static_cast<float>(WindowPosY));

    if (GEngine && GEngine->GameViewport)
    {
        TSharedPtr<SWindow> Window = GEngine->GameViewport->GetWindow();

        // Hack for linux
#if PLATFORM_LINUX
       const EWindowMode::Type CurrentWindowMode = Window->GetWindowMode();
       Window->SetWindowMode(EWindowMode::Windowed);
#endif

        Window->MoveWindowTo(Position);

#if PLATFORM_LINUX
        // Set back to original
        Window->SetWindowMode(CurrentWindowMode);
#endif
    }
}

I too am stuck with the “unresolved external symbol” error in the 4.19.2 version.

EDIT: I needed to include the following headers:

  • include “GenericApplication.h”
  • include “SWindow.h”

And add the following modules in my project’s Build.cs file:

  • ApplicationCore
  • SlateCore

Perfect, thank you. This is the complete answer!

How would I get the current (active) Display Index ?

It is explained in the answer
// Start monitor on the main screen

@henriquebach ,FDisplayMetrics is in module “ ApplicationCore“ with link:(ApplicationCore | Unreal Engine Documentation),you should add “ ApplicationCore“ to your xxx.build.cs