【问题标题】:How to resize display resolution on windows with nim如何使用 nim 在 Windows 上调整显示分辨率
【发布时间】:2021-04-12 21:01:28
【问题描述】:

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

我已经看到并使用了 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 之类的内容,但没有太大帮助,https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsa 也是如此

【问题讨论】:

    标签: nim-lang


    【解决方案1】:

    我自己写了大约 2% 的答案,其余的来自不和谐的 pointystick - 感谢他们! 该解决方案有点懒惰,但它是如此之快,以至于对于大多数人来说这并不重要。 如果没有 cmd 行参数,它只会将显示设置为默认建议,否则如果找到匹配项,如果有 2 个 cmd 行参数,它可以重置您的显示

    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"
    

    【讨论】:

    • 如果将wantedMode 声明为var,则可以使用addr 而不是unsafeAddr
    • 我相信你。这样做是否有充分的理由 - unsafeAddr 会导致问题吗?
    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    相关资源
    最近更新 更多