获取当前笔记本电脑盖状态

本文关键字:状态 电脑 笔记本 获取 | 更新日期: 2023-09-27 18:29:59

我正在编写一个C#应用程序(专门针对笔记本电脑),我想了解盖子的状态,即何时打开和何时关闭。

在这个SO答案的帮助下,我已经使用了pInvoke和Microsoft的RegisterPowerSettingNotification函数。

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

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

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

所以,(并非双关语)有没有办法马上得到这些信息?

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

关键词:GUID_LDSWITCH_STATE_CHANGE,WM_POWERBROADCAST,电源设置

获取当前笔记本电脑盖状态

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

请参见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中的盖子关闭事件设置为"Do Nothing",回调仍然会触发,您可能会考虑使用一个助手进程或服务来一直运行并跟踪更改。您可以通过注册表或文件共享状态。您还可以查看是否有任何其他硬件项目(如触摸板)在关闭时更改电源状态,而不考虑"电源计划",并使用GetDevicePowerState API功能。

因此,在@Llwyd的回答引导下进行了长时间的搜索后,我找到了一个解决方案。

我注意到,当盖子关闭时,设备会从设备管理器中取出,因此解决方案是检查它是否在那里。

在这里上传它背后的代码有点庞大,所以我不会,但需要以下内容:

  1. WmiMonitorConnectionParamsVideoOutputTechnology以及状态(DISPLAY_DEVICE_ATTACHED和/或DISPLAY_DEVICE_ACTIVE)识别内部屏幕的名称''ID。

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

这是在带有c++的窗口中执行此操作的一种方法:

static HPOWERNOTIFY sLidHandle = nullptr;
static HWND sHWnd_Lid = nullptr;
static int window_lid_state = 1;   // starts as open
static LRESULT CALLBACK LidWindowProc(HWND hwnd, UINT msg, WPARAM wParam,
                                          LPARAM lParam) {
  if (wParam == PBT_POWERSETTINGCHANGE){
      PPOWERBROADCAST_SETTING ptype = (PPOWERBROADCAST_SETTING)lParam;
      if ( ptype->PowerSetting == GUID_LIDSWITCH_STATE_CHANGE){
          window_lid_state = ptype->Data[0];
      }
  }
  return TRUE;
}
void EnableLidNotifications() {
  // Create custom window to watch Lid events
  if (sHWnd_Lid == nullptr) {
    WNDCLASSW wc;
    HMODULE hSelf = GetModuleHandle(nullptr);
    if (!GetClassInfoW(hSelf, L"wainCamLidClass", &wc)) {
      ZeroMemory(&wc, sizeof(WNDCLASSW));
      wc.hInstance = hSelf;
      wc.lpfnWndProc = LidWindowProc;
      wc.lpszClassName = L"waincamLidClass";
      RegisterClassW(&wc);
    }
    sHWnd_Lid = CreateWindowW(L"wainCamLidClass", L"Lid Watcher", 0, 0, 0,
                          0, 0, nullptr, nullptr, hSelf, nullptr);
  }
  window_lid_state = 1;
  sLidHandle = RegisterPowerSettingNotification(
     sHWnd_Lid,&GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);
}
int my_chk_lid_open(){
    int oflag = 1;
   static QMutex lidstate_mutex;
   if (sLidHandle == nullptr){
       lidstate_mutex.lock();
       if (sLidHandle == nullptr){
         EnableLidNotifications();
         my_assert(sLidHandle!=NULL,"");
       }
       lidstate_mutex.unlock();
   }
   oflag = window_lid_state;
   return(oflag);
}
main(){
   my_chk_lid_open();
   MSG msg;
   BOOL bRet;
   // need to process the initial message to detect the lid state
   bRet = GetMessage(&msg, NULL, 0, 0);  
   printf("laptop lid state=%s'n",my_chk_lid_open() ? "open" : "closed");
}