Page 1 of 2

[Solved] Setting desktop resolution on widescreen monitor

Posted: Fri Jun 11, 2021 12:36 pm
by BarryG
Hi all. I have a monitor that is normally set to 1920 x 1080 resolution (its native resolution). However, when I change it to something lower through Win 10's "Settings" on purpose, such as 1024 x 768, it looks nicely centered like this -> https://i.imgur.com/YbEyW7y.jpg

But when I do it with the following PureBasic code, the desktop is stretched to fit, which I don't want -> https://i.imgur.com/UvqKCWQ.jpg

Is there any way to make the code below NOT stretch it, so it's like the first image above? Thanks.

Code: Select all

res.DEVMODE\dmSize=SizeOf(DEVMODE)
res\dmPelsWidth=1024
res\dmPelsHeight=768
res\dmFields=#DM_PELSWIDTH|#DM_PELSHEIGHT
ChangeDisplaySettings_(@res,#CDS_UPDATEREGISTRY)

Re: Setting desktop resolution on widescreen monitor

Posted: Fri Jun 11, 2021 2:42 pm
by Mijikai
Try setting (DM_DISPLAYORIENTATION):

Code: Select all

DMDFO_CENTER

Re: Setting desktop resolution on widescreen monitor

Posted: Fri Jun 11, 2021 4:22 pm
by JHPJHP
Hi BarryG,

Have you tried the ChangeDisplaySettingsExW function?

Re: Setting desktop resolution on widescreen monitor

Posted: Fri Jun 11, 2021 11:41 pm
by BarryG
JHPJHP: That didn't work; my desktop is still stretched horizontally to fit, so all circles aren't perfectly round, etc.

Mijikai: I tried with "dmDisplayFixedOutput" but that's not supported by PureBasic:

Code: Select all

res.DEVMODE\dmSize=SizeOf(DEVMODE)
res\dmPelsWidth=1024
res\dmPelsHeight=768
res\dmDisplayFixedOutput=#DMDFO_CENTER ; Not supported.
res\dmFields=#DM_PELSWIDTH|#DM_PELSHEIGHT
ChangeDisplaySettings_(@res,#CDS_UPDATEREGISTRY)
Looks like some info is here -> https://stackoverflow.com/questions/651 ... tio-to-169

But I'm not sure how to apply any of it to my problem.

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 12:52 am
by JHPJHP
Hi BarryG,
BarryG wrote:I tried with "dmDisplayFixedOutput" but that's not supported by PureBasic
It's supported within a nested-structure.

Code: Select all

lpDevMode\Display\dmDisplayFixedOutput = #DMDFO_CENTER

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 1:06 am
by BarryG
Still no luck, JHPJHP. Thanks for trying. Your latest code doesn't change the resolution at all (your code just finishes without doing anything), but does if I remove the "#DM_DISPLAYFIXEDOUTPUT" flag; however removing that still makes the screen stretched and not centered.

I also tried this code without success (ie. it's still stretched):

Code: Select all

#DMDFO_CENTER=2
res.DEVMODE\dmSize=SizeOf(DEVMODE)
res\dmPelsWidth=1024
res\dmPelsHeight=768
res\dmFields=#DM_PELSWIDTH|#DM_PELSHEIGHT
res\Display\dmDisplayFixedOutput=#DMDFO_CENTER
ChangeDisplaySettings_(@res,#CDS_UPDATEREGISTRY)
Starting to wonder now if it's actually the monitor doing the stretching? But that wouldn't explain why changing the resolution in Win 10 "Settings" doesn't stretch it.

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 2:05 am
by JHPJHP
Hi BarryG,

My native resolution is also 1920 x 1080, and both configurations I posted work as expected.

Maybe use Device Manager to remove (delete) your monitor drivers, rebooting to a fresh install; should rule out a couple things.
Could be a corruption where Windows access to the driver remains intact, but API access has an issue.

Good luck.

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 8:35 am
by BarryG
Reinstalling the drivers and rebooting didn't help. Even this AutoHotkey script to resize (with 1024,768 edited in) didn't stop the stretch, even though it's apparently supposed to -> https://stackoverflow.com/a/65117925/7908170

For now I'm concluding this is some hardware feature of my monitor, since both PureBasic and AutoHotkey can't stop the stretch.

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 11:01 am
by RASHAD
Hi BarryG
Try

Code: Select all

#DMDFO_DEFAULT 	= 0
#DMDFO_STRETCH  = 1
#DMDFO_CENTER 	= 2

res.DEVMODE\dmSize=SizeOf(DEVMODE)
res\dmPelsWidth=1024
res\dmPelsHeight=768
res\Display\dmDisplayOrientation= #DMDFO_CENTER
res\dmFields=#DM_PELSWIDTH|#DM_PELSHEIGHT
ChangeDisplaySettings_(@res,#CDS_UPDATEREGISTRY)

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 11:39 am
by BarryG
No good, Rashad. I already tried your exact code already (see previous posts). Hehe.

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 12:30 pm
by RASHAD
No you did not :)
You tried

Code: Select all

res\Display\dmDisplayFixedOutput=#DMDFO_CENTER
mine :

Code: Select all

res\Display\dmDisplayOrientation= #DMDFO_CENTER
Be careful :lol:

Re: Setting desktop resolution on widescreen monitor

Posted: Sat Jun 12, 2021 1:12 pm
by BarryG
Oops, you're right, I missed that. So I tried it and the desktop is still stretched to fit (1024 pixels on a 1920 monitor).

Re: Setting desktop resolution on widescreen monitor

Posted: Sun Jun 13, 2021 12:38 am
by JHPJHP
Hi BarryG,

I may have found what is causing the issue and a possible fix; see a basic example of the SetDisplayConfig function below.
A working example can be found in Windows Services & Other Stuff.

Scaling the desktop image
Microsoft wrote:A caller can use the SetDisplayConfig Connecting and Configuring Displays (CCD) function to scale the desktop image to the monitor:

If the desktop and monitor use the same resolution, SetDisplayConfig is not required to scale the desktop image to the monitor. This SetDisplayConfig operation is known as identity scaling.

If the desktop and monitor resolution are different, SetDisplayConfig applies one of the following types of scaling...

Code: Select all

#SDC_TOPOLOGY_EXTEND = $4
#SDC_APPLY = $80

#ERROR_BAD_CONFIGURATION = $488

Prototype.l protoSetDisplayConfig(numPathArrayElements, *pathArray, numModeInfoArrayElements, *modeInfoArray, flags)
Global SetDisplayConfig.protoSetDisplayConfig

user32 = OpenLibrary(#PB_Any, "user32.dll")

If IsLibrary(user32)
  SetDisplayConfig = GetFunction(user32, "SetDisplayConfig")
  nResult = SetDisplayConfig(0, #Null, 0, #Null, #SDC_TOPOLOGY_EXTEND | #SDC_APPLY)

  Select nResult
    Case #ERROR_SUCCESS
      Debug "ERROR_SUCCESS"
    Case #ERROR_INVALID_PARAMETER
      Debug "ERROR_INVALID_PARAMETER"
    Case #ERROR_NOT_SUPPORTED
      Debug "ERROR_NOT_SUPPORTED"
    Case #ERROR_ACCESS_DENIED
      Debug "ERROR_ACCESS_DENIED"
    Case #ERROR_GEN_FAILURE
      Debug "ERROR_GEN_FAILURE"
    Case #ERROR_BAD_CONFIGURATION
      Debug "ERROR_BAD_CONFIGURATION"
  EndSelect
  CloseLibrary(user32)
EndIf

Re: Setting desktop resolution on widescreen monitor

Posted: Sun Jun 13, 2021 2:45 am
by BarryG
JHPJHP wrote: Sun Jun 13, 2021 12:38 am

Code: Select all

#SDC_TOPOLOGY_EXTEND = $4
#SDC_APPLY = $80

#ERROR_BAD_CONFIGURATION = $488

Prototype.l protoSetDisplayConfig(numPathArrayElements, *pathArray, numModeInfoArrayElements, *modeInfoArray, flags)
Global SetDisplayConfig.protoSetDisplayConfig

user32 = OpenLibrary(#PB_Any, "user32.dll")

If IsLibrary(user32)
  SetDisplayConfig = GetFunction(user32, "SetDisplayConfig")
  nResult = SetDisplayConfig(0, #Null, 0, #Null, #SDC_TOPOLOGY_EXTEND | #SDC_APPLY)

  Select nResult
    Case #ERROR_SUCCESS
      Debug "ERROR_SUCCESS"
    Case #ERROR_INVALID_PARAMETER
      Debug "ERROR_INVALID_PARAMETER"
    Case #ERROR_NOT_SUPPORTED
      Debug "ERROR_NOT_SUPPORTED"
    Case #ERROR_ACCESS_DENIED
      Debug "ERROR_ACCESS_DENIED"
    Case #ERROR_GEN_FAILURE
      Debug "ERROR_GEN_FAILURE"
    Case #ERROR_BAD_CONFIGURATION
      Debug "ERROR_BAD_CONFIGURATION"
  EndSelect
  CloseLibrary(user32)
EndIf
I get an ERROR_GEN_FAILURE error when running that, so I don't think it will help my situation. Thanks anyway.

Re: Setting desktop resolution on widescreen monitor

Posted: Sun Jun 13, 2021 9:14 am
by JHPJHP
Hi BarryG,

I don't think you fully read my post...
If you followed the link, it explained that the function SetDisplayConfig replaced the legacy function ChangeDisplaySettings for newer OS.

My previous example was only meant to get you started, not a complete solution; I've updated the post to be a bit more clear.