Sigh.
If you are not a programmer, then why are you messing with this?
I understand that finding and using programming-related information on the internet can be overwhelming for a beginner.
The code is not all that difficult, actually.
To GET the current topology mode, you need
QueryDisplayConfig().
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-querydisplayconfig
To SET the current topology mode, you need
SetDisplayConfig(), which requires Windows 7 and up (satisfying your requirements).
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setdisplayconfig
Admittedly, neither article is particularly simple to read, especially for a noob. So... against my better judgement, here is a working C++ library to make using it easy, plus an example command-line program to demonstrate using it:
display_topology.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
/*
Copyright 2019 Michael Thomas Greer
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
https://www.boost.org/LICENSE_1_0.txt )
*/
#ifndef DISPLAY_TOPOLOGY_HPP
#define DISPLAY_TOPOLOGY_HPP
enum class DisplayTopology
{
Internal,
Clone,
Extend,
External,
Error
};
DisplayTopology GetDisplayTopology();
bool SetDisplayTopology( DisplayTopology topology );
#endif
| |
display_topology.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
/*
Copyright 2019 Michael Thomas Greer
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
https://www.boost.org/LICENSE_1_0.txt )
*/
#include "display_topology.hpp"
#include <ciso646>
#include <windows.h>
#pragma comment( lib, "User32.lib" )
//-------------------------------------------------------------------------------------------------
DisplayTopology GetDisplayTopology()
{
UINT32 numPathArrayElements;
UINT32 numModeInfoArrayElements;
GetDisplayConfigBufferSizes( QDC_DATABASE_CURRENT, &numPathArrayElements, &numModeInfoArrayElements );
auto pathArray = new DISPLAYCONFIG_PATH_INFO[ numPathArrayElements ];
auto modeInfoArray = new DISPLAYCONFIG_MODE_INFO[ numModeInfoArrayElements ];
DISPLAYCONFIG_TOPOLOGY_ID currentTopologyId;
auto ok = QueryDisplayConfig( QDC_DATABASE_CURRENT,
&numPathArrayElements, pathArray,
&numModeInfoArrayElements, modeInfoArray,
¤tTopologyId );
delete [] pathArray;
delete [] modeInfoArray;
if (ok == ERROR_SUCCESS) switch (currentTopologyId)
{
case DISPLAYCONFIG_TOPOLOGY_INTERNAL: return DisplayTopology::Internal;
case DISPLAYCONFIG_TOPOLOGY_CLONE: return DisplayTopology::Clone;
case DISPLAYCONFIG_TOPOLOGY_EXTEND: return DisplayTopology::Extend;
case DISPLAYCONFIG_TOPOLOGY_EXTERNAL: return DisplayTopology::External;
default: break;
}
return DisplayTopology::Error;
}
//-------------------------------------------------------------------------------------------------
bool SetDisplayTopology( DisplayTopology topology )
{
UINT32 topologies[] =
{
SDC_TOPOLOGY_INTERNAL,
SDC_TOPOLOGY_CLONE,
SDC_TOPOLOGY_EXTEND,
SDC_TOPOLOGY_EXTERNAL
};
if (topology == DisplayTopology::Error) return false;
return SetDisplayConfig( 0, NULL, 0, NULL, topologies[(int)topology] | SDC_APPLY ) == ERROR_SUCCESS;
}
| |
example.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
/*
Copyright 2019 Michael Thomas Greer
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
https://www.boost.org/LICENSE_1_0.txt )
*/
#include <cctype>
#include <iostream>
#include <string>
#include "display_topology.hpp"
//-------------------------------------------------------------------------------------------------
void set_topology( std::string&& mode )
{
for (auto& c : mode) c = std::tolower( c & 0x7F );
DisplayTopology topology =
(mode == "internal" ) ? DisplayTopology::Internal :
(mode == "clone" ) ? DisplayTopology::Clone :
(mode == "duplicate") ? DisplayTopology::Clone :
(mode == "extend" ) ? DisplayTopology::Extend :
(mode == "external" ) ? DisplayTopology::External :
DisplayTopology::Error;
if (topology == DisplayTopology::Error) throw "Argument must be one of 'internal', 'clone', 'duplicate', 'extend', or 'external'";
if (!SetDisplayTopology( topology )) throw "Could not change display topology";
}
//-------------------------------------------------------------------------------------------------
void get_topology()
{
static const char* topologies[] =
{
"internal",
"clone",
"extend",
"external",
nullptr
};
auto topology = topologies[ (int)GetDisplayTopology() ];
if (!topology) throw "Failure to identify the current display topology";
std::cout << topology << "\n";
}
//-------------------------------------------------------------------------------------------------
int main( int argc, char** argv )
try
{
if (argc == 2) set_topology( argv[1] );
else get_topology();
}
catch (const char* error_message)
{
std::cerr << error_message << "\n";
return 1;
}
| |
To compile with MSVC, just add all files to your project and build, or from the command line:
C:\Users\montra\programming> cl /EHsc /Ox /std:c++latest example.cpp display_topology.cpp |
To comple with GCC (“g++”) or Clang (“clang++”) from the command line:
C:\Users\montra\programming> clang++ -std=c++17 -Wall -pedantic -O3 example.cpp display_topology.cpp -o example.exe |
Test it with the usual:
C:\Users\montra\programming> example help
Argument must be one of 'internal', 'clone', 'duplicate', 'extend', or 'external'
C:\Users\montra\programming> example
internal
C:\Users\montra\programming> example clone
C:\Users\montra\programming> example
clone
C:\Users\montra\programming> |
“Clone” and “duplicate” mean the same thing.
The example program should be enough to show you how to use the library in whatever program you are trying to create.
Your company’s legal department should not find anything objectionable about the Boost Software License. You can read more here:
https://www.boost.org/users/license.html
Beware, I’m a jealous bastard. Don’t screw me over for being nice.
In the future, it is much more helpful to explain everything you want right up front, and (since it is your responsibility to learn this stuff) it helps to google around the terms you find. For example, you can google
“setdisplayconfig clone example”
Which brings up a whole list of hits
https://www.google.com/search?q=setdisplayconfig+clone+example
At least one of them has working code you could have easily chosen.
Good luck!