【发布时间】:2014-07-09 05:02:26
【问题描述】:
我正在制作一个可以做很多事情的实用程序脚本。我想做的一件事是旋转显示器;我有多个显示器,我希望主显示器旋转。我知道这种事情通常可以通过win32api 工作,并且我在那里发现了一些看起来很有帮助的功能,但我正在努力实现。
此行和下一行之间的所有内容都已过时,请参阅下面的第二行了解解决方案尝试的最新描述
在将我的脸埋在文档中之后,恐怕我仍然没有太多关于如何前进的想法,除了它可能涉及win32api.ChangeDisplaySettingsEx()。我知道我需要给该函数一个指向DEVMODE 对象的指针(甚至不确定如何在python 中使用C 指针),我想我可以从win32api.EnumDisplaySettingsEx() 获得。所以如果我尝试,
>>> import win32api as win32
>>> a = win32.EnumDisplayDevices()
>>> type(a)
我应该得到一些涉及 DEVMODE 指针或其他东西的东西,但我得到了
>>> type(a)
<type 'PyDISPLAY_DEVICE'>
我不知道该怎么办,但我认为this is the structure
那么,我如何获得一个DEVMODE ojbect 我可以提供给ChangeDisplaySettingsEx(),以便我可以旋转我的一个显示器?提前致谢。
我在 Windows 7 上运行 Python 2.7
编辑:如果我真的使用了正确的功能,它仍然不起作用。会不会是 Python 模块不完整?
>>> a = win32.EnumDisplaySettings()
>>> type(a)
<type 'PyDEVMODEA'>
>>> a.dmSize
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PyDEVMODEA' object has no attribute 'dmSize'
>>> a.dmScale
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PyDEVMODEA' object has no attribute 'dmScale'
>>> a.dmDisplayOrientation
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PyDEVMODEA' object has no attribute 'dmDisplayOrientation'
现在,我注意到这给了我一个DEVMODEA 对象而不是DEVMODE,但this page 说它们是相同的。这可能是什么问题?
编辑:现在我使用了正确的属性名称,我可以得到一个有效的DEVMODEA 对象:
>>> a = win32.EnumDisplaySettings()
>>> a.Size
124L
>>> a.DisplayOrientation
0L
并改变对象的方向:
>>> a.DisplayOrientation = 90L
>>> a.DisplayOrientation
90L
然后我可以尝试通过将此DEVMODEA 对象赋予ChangeDisplaySettingsEx() 来“应用”这些更改
>>> win32.ChangeDisplaySettingsEx(a.DeviceName, a, 0)
-5L
这无济于事。不幸的是,the docs 在帮助我解释返回值方面并不是很有用。我假设-5L 是某种错误代码,因为它不起作用,但我无法知道是哪一个。这个返回值是什么意思,如何让我的新 DEVMODEA 对象“应用”
我发现-5L 返回值表示参数错误。具体来说,它对第一场比赛很生气。如果我用DISPLAY_DEVICE.DeviceName 替换它,我会得到-2L 结果。这对应于不良模式(无论是什么)。即使我给ChangeDisplaySettingsEx() 提供的正是EnumDisplaySettings() 输出的内容,也会发生这种情况。
到目前为止我的进展:
>>> import win32api as win32
>>> import win32con
>>> a = win32.EnumDisplaySettings()
>>> a.DisplayOrientation
0L
>>> a.DisplayOrientation = win32con.DMDO_90
>>> a.DisplayOrientation
1L
>>> a.PelsWidth, a.PelsHeight = a.PelsHeight, a.PelsWidth
>>> a.Fields = a.Fields & win32con.DM_DISPLAYORIENTATION
>>> name = win32.EnumDisplayDevices().DeviceName
>>> name
'\\\\.\\DISPLAY1'
>>> win32.ChangeDisplaySettingsEx(name, a)
-2L
最近一次尝试(美国东部标准时间 6 月 4 日上午 10:50)
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32api as win32
>>> import win32con
>>>
>>> device = win32.EnumDisplayDevices(None, 1)
>>> print "Rotate device {} ({})".format(device.DeviceString, device.DeviceName)
Rotate device Intel(R) HD Graphics 4000 (\\.\DISPLAY2)
>>>
>>> dm = win32.EnumDisplaySettings(device.DeviceName, win32con.ENUM_CURRENT_SETTINGS)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pywintypes.error: (0, 'EnumDisplaySettings', 'No error message is available')
>>>
>>> dm = win32.EnumDisplaySettings(device.DeviceName)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pywintypes.error: (123, 'EnumDisplaySettings', 'The filename, directory name, or volume label syntax is incorrect.')
>>>
>>> dm = win32.EnumDisplaySettings(device.DeviceName, win32con.ENUM_CURRENT_SETTINGS)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pywintypes.error: (123, 'EnumDisplaySettings', 'The filename, directory name, or volume label syntax is incorrect.')
>>>
注意第一次和第三次创建dm 的尝试如何失败尽管代码相同。
【问题讨论】:
-
这不是
win32api模块应该做的吗? -
文档指出,
EnumDisplaySettings()返回您预期的DEVMODE。但是,在您的示例代码中,您调用EnumDisplayDevices(),这是一个不同的函数。后者正确返回DISPLAY_DEVICE。我很快观察到 PyWin32 的来源,EnumDisplaySettings()似乎可用。不幸的是,我还没有测试它,但我确信它会起作用。 -
@Bengt,哎呀,这是一个愚蠢的错误,感谢您指出这一点!
-
您需要一个带有电动旋转功能的显示器和一个合适的 API 来控制它。或者,也许您只是想旋转显示 :)