如何使用 nim 在 windows 上调整显示分辨率

How to resize display resolution on windows with nim

我想使用 nim 来调整机器上的默认显示分辨率(windows 10),我想基本上通过像 setDisplay 1280 1024[= 这样的命令行调用来完成15=]

我看过并使用了 python 示例 Resize display resolution using python with cross platform support,我可以理解,但无法翻译。我只是不知道如何填写 EnumDisplaySettings

import winim/lean
import strformat

var
  cxScreen = GetSystemMetrics(SM_CXSCREEN)
  cyScreen = GetSystemMetrics(SM_CYSCREEN)
  msg = fmt"The screen is {cxScreen} pixels wide by {cyScreen} pixels high."
EnumDisplaySettings(Null,0, 0) #total type mismatch

MessageBox(0, msg, "Winim Example Screen Size", 0)

尝试检查 https://cpp.hotexamples.com/fr/examples/-/-/EnumDisplaySettings/cpp-enumdisplaysettings-function-examples.html but wasn't much help, same for https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsa

之类的内容

我自己写了大约 2% 的答案,其余部分来自 discord 上的 pointystick - 感谢他们! 该解决方案有点懒惰,但它是如此之快,以至于对大多数人来说都无关紧要。 如果没有 cmd line args,它只会将显示设置为默认建议,否则使用 2 cmd line args 如果找到匹配项,它可以重置您的显示

import winim/lean
import os
import strutils

var modeToFind = (width: 1920, height: 1080, bitsPerPixel: 32,
    refreshRate: 60)
var reset = 0

type ModeNotFoundError = object of CatchableError

proc getDisplayMode(): DEVMODEW =
  ## Finds the wanted screen resolution or raises a ModeNotFoundError.

  var
    nextMode: DWORD = 0
    mode: DEVMODEW

  while EnumDisplaySettings(nil, nextMode, mode) != 0:
    echo $mode.dmPelsWidth & " x " & $mode.dmPelsHeight &
        " x " & $mode.dmBitsPerPel &
        " - " & $mode.dmDisplayFrequency
    inc nextMode

    if (mode.dmPelsWidth == modeToFind.width) and
       (mode.dmPelsHeight == modeToFind.height):
      echo "Found it!"
      return mode

  if(reset==1):
    return mode
  raise newException(ModeNotFoundError, "Cannot find wanted screen mode")

proc changeResolution(): bool =
  ## Actually changes the resolution.  The return value indicates if it worked.
  result = false
  try:
    let wantedMode = getDisplayMode()
    result = ChangeDisplaySettings(wantedMode.unsafeAddr, 0.DWORD) == DISP_CHANGE_SUCCESSFUL
  except ModeNotFoundError: discard

when isMainModule:
  var
    cxScreen:int32 = 0 #= GetSystemMetrics(SM_CXSCREEN)
    cyScreen:int32 = 0 # = GetSystemMetrics(SM_CYSCREEN)

  try:
    cxScreen = (int32) parseInt(paramStr(1))
    cyScreen = (int32) parseInt(paramStr(2))
    modeToFind.width = cxScreen
    modeToFind.height = cyScreen
  except:
    reset = 1

  if not changeResolution():
    echo "Change Resolution Failed"