【问题标题】:How to call user32.dll's EnumDisplaySettingsA in go如何在 go 中调用 user32.dll EnumDisplaySettings
【发布时间】:2020-12-13 15:47:48
【问题描述】:

我正在尝试通过 Win32 API 获取显示信息。到目前为止,我已经很好地管理了 EnumDisplayDevicesA,但是 EnumDisplaySettingsA 给我带来了麻烦。

无论我如何设置前两个变量,该函数都返回零(表示失败),没有关于它失败的原因的额外信息。

这是我的代码的精简版本,其中仅包含有问题的函数;

package main

import (
    "fmt"
    "syscall"
    "unsafe"
)

var (
    dll                 = syscall.MustLoadDLL("user32.dll")
    enumDisplaySettings = dll.MustFindProc("EnumDisplaySettingsA")
)

type devMode struct {
    dmDeviceName       [32]uint16
    dmSpecVersion      uint16
    dmDriverVersion    uint16
    dmSize             uint16
    dmDriverExtra      uint16
    dmFields           uint32
    dmOrientation      int16
    dmPaperSize        int16
    dmPaperLength      int16
    dmPaperWidth       int16
    dmScale            int16
    dmCopies           int16
    dmDefaultSource    int16
    dmPrintQuality     int16
    dmColor            int16
    dmDuplex           int16
    dmYResolution      int16
    dmTTOption         int16
    dmCollate          int16
    dmFormName         [32]uint16
    dmLogPixels        uint16
    dmBitsPerPel       uint32
    dmPelsWidth        uint32
    dmPelsHeight       uint32
    dmDisplayFlags     uint32
    dmDisplayFrequency uint32
    dmICMMethod        uint32
    dmICMIntent        uint32
    dmMediaType        uint32
    dmDitherType       uint32
    dmReserved1        uint32
    dmReserved2        uint32
    dmPanningWidth     uint32
    dmPanningHeight    uint32
}

func queryDisplaySettings() devMode {
    out := devMode{}
    out.dmSize = uint16(unsafe.Sizeof(out))
    outptr := uintptr(unsafe.Pointer(&out))

    namePtr := uintptr(unsafe.Pointer(nil))

    var iModeNum uint32 = 4294967295
    enumCurrentSettings := uintptr(unsafe.Pointer(&iModeNum))

    ret, _, _ := enumDisplaySettings.Call(namePtr, enumCurrentSettings, outptr)
    if ret == 0 {
        fmt.Printf("Failed EnumDisplaySettings")
    }
    return out
}

func main() {
    settings := queryDisplaySettings()

    fmt.Printf("\n%v\n", settings.dmPelsWidth)
    fmt.Printf("%v\n", settings.dmPelsHeight)
    fmt.Printf("%v\n\n", settings.dmDisplayFrequency)
}

我的消息来源:

【问题讨论】:

  • 你能解释更多吗?
  • 我不太清楚你要什么。

标签: go winapi user32


【解决方案1】:

这里的代码存在多个问题。

首先,您的 devMode 类型定义是针对 DEVMODEW,但您正在调用 EnumDisplaySettingsA。但是,您不应该首先调用它(它是 ANSI 版本),所以请改用 EnumDisplaySettingsW (UNICODE)。

接下来,EnumDisplaySettingsA/EnumDisplaySettingsW 的第二个参数是一个 DWORD (uint32),但是您将地址传递给它,而不是传递值。

所以替换

var iModeNum uint32 = 4294967295
enumCurrentSettings := uintptr(unsafe.Pointer(&iModeNum))

只要

iModeNum := uintptr(4294967295)

这一切都应该正常工作。

【讨论】:

  • 您先生/女士,是救生员。代码现在可以工作了,我可以不用再为此烦恼了,谢谢!
猜你喜欢
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多