Chris Chris - 3 months ago 12
C++ Question

Code works only in Visual Studio Debug but not in release mode nor .exe

I've wrote an application to change the display resolution. (I'm used to play CS at 4:3 resolution and working at 16:9 and I'm too lazy to go to Systemcontrol and change it there.)

The program works fine as long as i run it with Visual Studio (Pro 2013) in Debug Mode, but if I change to Release Mode or try to run the .exe files it doesnt work.

Edit: I've got no errors and it looks like it does change the resolution (black monitor) but it does'nt change the resolution. Also tried to run wih admin rights.

Does anyone has an idea to solve my problem?

Thanks in advance!

Code:

#include <Windows.h>

struct SResolution
{
int x;
int y;
};

static SResolution R_1440x1080 = { 1440, 1080 };
static SResolution R_1920x1080 = { 1920, 1080 };

bool GetPrimaryDisplayDevice(DISPLAY_DEVICE& _rDisplayDevice);

int main()
{
SResolution Resolution = R_1920x1080; // R_1440x1080 R_1920x1080

DISPLAY_DEVICE DDevice;
DEVMODE lpDevMode;
DEVMODE lpDevMode2;

ZeroMemory(&DDevice , sizeof(DDevice));
ZeroMemory(&lpDevMode , sizeof(lpDevMode));
ZeroMemory(&lpDevMode2, sizeof(lpDevMode2));

DDevice.cb = sizeof(DDevice);
lpDevMode .dmSize = sizeof(lpDevMode);
lpDevMode2.dmSize = sizeof(lpDevMode2);

if (!GetPrimaryDisplayDevice(DDevice)) return 0;

if (!EnumDisplaySettings(DDevice.DeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode)) return 0;

// if (Resolution.x == lpDevMode.dmPelsWidth && Resolution.y == lpDevMode.dmPelsHeight) return 0;

int i = 0;

while (EnumDisplaySettings(DDevice.DeviceName, i, &lpDevMode))
{
if (Resolution.x == lpDevMode.dmPelsWidth && Resolution.y == lpDevMode.dmPelsHeight)
{
lpDevMode2 = lpDevMode;
}

i++;
}

lpDevMode2.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;

DWORD Flags = CDS_UPDATEREGISTRY | CDS_FULLSCREEN;

if (ChangeDisplaySettings(&lpDevMode2, Flags) != DISP_CHANGE_SUCCESSFUL)
{
MessageBox(NULL, (LPCWSTR)L"Fail", (LPCWSTR)L"Error", MB_ICONHAND);
}

return 0;
}

bool GetPrimaryDisplayDevice(DISPLAY_DEVICE& _rDisplayDevice)
{
DWORD NumberOfDevice = 0;
DWORD dwFlags = 0;

while (EnumDisplayDevices(NULL, NumberOfDevice, &_rDisplayDevice, dwFlags))
{
DISPLAY_DEVICE InnerDDevice = { 0 };
DWORD InnerNumberOfDevice = 0;

ZeroMemory(&InnerDDevice, sizeof(InnerDDevice));
InnerDDevice.cb = sizeof(DISPLAY_DEVICE);

if (_rDisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{
return true;
}

NumberOfDevice++;
}

return false;
}


Edit2: Solved. - the problem was the CDS_FULLSCREEN flag at:

DWORD Flags = CDS_FULLSCREEN | CDS_UPDATEREGISTRY;

ChangeDisplaySettings(&DMode, CDS_UPDATEREGISTRY);


I've deleted this flag and only use CDS_UPDATEREGISTRY. Now it works.

Thanks to everyone who helped me or gave me tips :)

Answer

It actually does change the resolution. Add an else statement after this

if (ChangeDisplaySettings(&lpDevMode2, Flags) != DISP_CHANGE_SUCCESSFUL)
{
    MessageBox(NULL, (LPCWSTR)L"Fail", (LPCWSTR)L"Error", MB_ICONHAND);
}

like this

else 
{
    MessageBox(NULL, (LPCWSTR)L"Success", (LPCWSTR)L"Congrats", MB_ICONHAND);
}

And you will see that the resolution has changed but switched back when the program finished.

I wanted to post it as a comment since I don't know how to fix it, but I don't have enough reputation for commenting yet.