【问题标题】:Get current laptop lid state获取当前笔记本电脑盖状态
【发布时间】:2015-01-08 07:15:42
【问题描述】:

我正在编写一个 C# 应用程序(专门用于笔记本电脑),我想知道盖子的状态,即它什么时候打开,什么时候关闭。

this SO answer 的帮助下,我已经使用了 pInvoke 和 Microsoft's RegisterPowerSettingNotification function

因此,通过以上内容,我知道盖子何时关闭或打开并知道其状态, 但我想在其他任何事情继续之前得到盖子的状态。 我注意到即使盖子没有变化,也会调用回调函数,我可以检查它的参数以了解盖子的状态,但这对我不利,因为它是一个事件,我不能简单地等待让它发生(也许有另一种方法可以解决这个问题?)。

我也尝试过 PowerEnumerate 函数,但无法从中获得一些东西(也许有一些我不知道的东西可以提供帮助)

编辑 1: 我不能等待或延迟应用程序,有两个问题需要我在没有 CB 的情况下获得状态,第一个是在笔记本电脑连接到显示器时可以关闭盖子,从而允许用户使用笔记本电脑。如果用户在这种情况下启动应用程序,它不应该启动。 第二个原因是我希望应用程序对用户友好,并通知它启动或停止时会发生什么,如果我在错误的时间得到 cb,由于应用程序的内部逻辑,它可能会被忽略,然后必须等到下次我拿到cb时,我会的。

所以,(没有双关语) 有没有办法立即获取这些信息?

编辑 2: 从 cmets 看来,我不清楚我需要什么。我需要一种查询盖子状态的方法。即 - 调用一些 API 或其他东西,返回值是状态。 谢谢!

关键字:GUID_LIDSWITCH_STATE_CHANGE、WM_POWERBROADCAST、电源设置

【问题讨论】:

  • 可能你没看我写的内容
  • 缓存最后的结果怎么样?
  • 在 WinAPI 术语中(根据需要转换为 C++/C#)如何在该事件中使用 CreateEvent() 然后 WaitForSingleObject() ;当盖子状态回调触发时,它可以将事件设置为已发出信号并且主程序可以继续。您可能希望 WFSO 调用超时,以防回调永远不会触发(此时您可以中止或假定适当的盖子状态)。
  • 该应用程序需要大约 3-5 秒才能开始运行,我不想再添加任何延迟。我已经有一个可行的解决方法,但我不想就这样离开它

标签: c# c++ winapi


【解决方案1】:

我不认为“盖子状态”一定会反映在电源管理属性中。您对盖子状态的兴趣是否仅仅取决于显示器?如果是这样,您可以找到一种方法来确定集成屏幕的属性(如果他们在连接到外部显示器时安装它可能会出现问题)并保存它们。然后检查正在使用的屏幕的属性并采取相应措施。

请参阅 System.Windows.Forms.Screen - http://msdn.microsoft.com/en-us/library/system.windows.forms.screen%28v=vs.110%29.aspx

序列号可以从HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY 中的“设备参数”键中提取。此处演示了如何提取它(以及其他信息):

http://sourceforge.net/p/wmimonitor/code/HEAD/tree/DisplayInfoWMIProvider/WMIProvider/WMIProvider.cs

或者,假设即使 Windows 中的盖子关闭事件设置为“什么都不做”,回调仍然会触发,您也许可以考虑让帮助程序或服务一直运行并跟踪更改。您可以通过注册表或文件共享状态。您还可以查看是否有任何其他硬件项目(例如触摸板)在关闭时更改电源状态,而不管“电源计划”如何,并使用 GetDevicePowerState API 函数。

【讨论】:

  • 你能解释一下为什么不吗?可能有另一种方式,但 ACPI 是特定于硬件/制造商的。考虑到从启动时跟踪变化并不令人满意,根据提供的信息检测笔记本电脑屏幕是否开机/连接似乎是一项非常明智的工作
  • 第一个建议不是一个明智的解决方法,因为它没有明确告诉我盖子是打开\关闭的。关于有另一种方式,可能还有另一种方式-我在其他地方查过,但找不到任何东西,这就是我在这里寻求帮助的原因。让我知道我可以尝试找到解决方案,而不是告诉我如何不是很有帮助。感谢您的尝试,但我想要更具体的内容。
【解决方案2】:

所以,在@Llwyd 的回答带领下进行了长时间的搜索之后,我找到了解决方案。

我注意到当盖子关闭时,设备从设备管理器中删除,所以解决方法是检查它是否存在。

后面的代码有点大,这里就不上传了,不过需要下面的:

  1. WmiMonitorConnectionParamsVideoOutputTechnology 和状态(DISPLAY_DEVICE_ATTACHED 和/或DISPLAY_DEVICE_ACTIVE)标识内部屏幕的名称\ID。

  2. 一旦我知道设备的名称/ID,就可以通过枚举System.Windows.Forms.Screen.AllScreens(或保存DISPLAY_DEVICE_ATTACHED 中的值)轻松查找它。

【讨论】:

  • 我希望你能在 github repo 或至少一个要点中分享代码。
  • 查看C++ codeC# code
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 2011-12-08
  • 1970-01-01
  • 2011-01-14
  • 2019-07-30
  • 2014-03-28
  • 2010-10-21
  • 1970-01-01
相关资源
最近更新 更多