![](https://habrastorage.org/getpro/geektimes/post_images/038/92e/4d9/03892e4d99ef94303e5584c60eee974e.png)
なぜなら 私は別のメーカーのラップトップを持っていますが、このソフトウェアをメーカーからスクラッチする方法を探すのが面倒でした-アナログを探し始めましたが、驚いたことに何も見つかりませんでした! (私が間違っている場合-あなたの鼻で見せて、私は非常に感謝します!)
それが私が決定を書くことにした方法です。 C ++で記述します。 Visual Studio 2010で作成しましたが、以前のバージョンを使用できます。 主なものは、インストールされたWindows SDKの存在です(スタジオとは別にインストールされ、無料で利用できます。たとえばここからダウンロードできます)。
ここに私が得たものがあります:
![私のソケット](http://pic.ipicture.ru/uploads/091116/hSZ5SqzZ3L.png)
ほとんどの場合、データ表示をプッシュしたい正確な場所の名前をインターネットで検索する必要がありました。 DeskBandと呼ばれ、 何よりも素晴らしいのは、Windows SDKの動作例です! (C:\ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Samples \ winui \ shell \ shellextensibility \ deskbandsにあります)。
次に、それは小さかった-バッテリーの充電に関する情報を取得する方法を見つける必要があります。 MSDNと組み合わせた検索エンジンにより、RegisterPowerSettingNotificationという便利な機能が実現しました。 そのマイナス-Windows Vista以降でのみサポートされていますが、これは私を止めませんでした。 私は自分で書いて、個人的には、すでにどこでもWindows 7を使用しています。
その構文は次のとおりです。
Copy Source | Copy HTML HPOWERNOTIFY WINAPI RegisterPowerSettingNotification( __in HANDLE hRecipient, __in LPCGUID PowerSettingGuid, __in DWORD Flags );
Copy Source | Copy HTML HPOWERNOTIFY WINAPI RegisterPowerSettingNotification( __in HANDLE hRecipient, __in LPCGUID PowerSettingGuid, __in DWORD Flags );
Copy Source | Copy HTML HPOWERNOTIFY WINAPI RegisterPowerSettingNotification( __in HANDLE hRecipient, __in LPCGUID PowerSettingGuid, __in DWORD Flags );
Copy Source | Copy HTML HPOWERNOTIFY WINAPI RegisterPowerSettingNotification( __in HANDLE hRecipient, __in LPCGUID PowerSettingGuid, __in DWORD Flags );
Copy Source | Copy HTML HPOWERNOTIFY WINAPI RegisterPowerSettingNotification( __in HANDLE hRecipient, __in LPCGUID PowerSettingGuid, __in DWORD Flags );
Copy Source | Copy HTML HPOWERNOTIFY WINAPI RegisterPowerSettingNotification( __in HANDLE hRecipient, __in LPCGUID PowerSettingGuid, __in DWORD Flags );
この関数は、サービスと通常のアプリケーション(使用する)の両方の作業をサポートします。
始めるために、DeskBandの使用例を別のフォルダーにコピーして、編集を開始しました。
次のようにWM_CREATEイベントハンドラーで呼び出します。
Copy Source | Copy HTML
- h1 = RegisterPowerSettingNotification(pDeskBand-> m_hwnd、&GUID_ACDC_POWER_SOURCE、DEVICE_NOTIFY_WINDOW_HANDLE);
- if (h1 == 0 )pDeskBand-> CloseDW( 1 );
- h2 = RegisterPowerSettingNotification(pDeskBand-> m_hwnd、&GUID_BATTERY_PERCENTAGE_REMAINING、DEVICE_NOTIFY_WINDOW_HANDLE);
- if (h2 == 0 )
- {
- UnregisterPowerSettingNotification(h1);
- pDeskBand-> CloseDW( 1 );
- }
h1とh2は、HPOWERNOTIFY型のグローバル(キックしないでください!)変数であり、本質的に同じハンドルです。
そこで、充電ケーブルの挿入/取り外しとバッテリーの残りの割合の変更のイベントを受け取るようにサインアップしました。 GUID_POWERSCHEME_PERSONALITYを使用して、サブスクライブして電源設定を変更することもできます。
ところで、デストラクタでは、たとえばh1とh2のUnregisterPowerSettingNotificationを作成することを忘れないでください。
また、グローバルに設定します(ただし、腎臓には設定しません!)バッテリーの充電と充電状態を保存するための変数:
Copy Source | Copy HTML
- bool isOnBattery = false ;
- int charge = -1;
そして、WM_POWERBROADCASTイベントハンドラーで:
Copy Source | Copy HTML
- POWERBROADCAST_SETTING * pps =(POWERBROADCAST_SETTING *)lParam;
- if ( sizeof ( int )== pps-> DataLength && pps-> PowerSetting == GUID_ACDC_POWER_SOURCE)
- {
- int nPowerSrc = *( int *)(DWORD_PTR)pps->データ;
- isOnBattery =( 0 != nPowerSrc);
- }
- else if ( sizeof ( int )== pps-> DataLength && pps-> PowerSetting == GUID_BATTERY_PERCENTAGE_REMAINING)
- {
- 充電済み= *( int *)(DWORD_PTR)pps->データ;
- }
- pDeskBand-> OnPaint(NULL);
これは何をしますか? WM_POWERBROADCASTイベントを受信すると、POWERBROADCAST_SETTING構造体へのポインターがlParamに渡され、受信します。 なぜなら この構造自体も中程度に歪んでいるので、この塗りつぶされた構造が正確に対応するイベントを調べます。
さらに、これが接続の充電イベントである場合、何が起こったのかを調べます。 0はバッテリー、1は充電中、2はUPSです(どこかで被写体が点灯するのを見たことはありません)。 さて、結果を変数isOnBatteryに保存します(バッテリの場合はtrue、そうでない場合はfalse)。
これがバッテリー充電率の変化のイベントである場合は、充電レベルを自分で維持します。 次に、再描画を呼び出します。
まず、何を描くかを決める必要があります。 私は電池の美しい写真を探すのが面倒だったので、私は単にテキストを美しく表示することにしました。 そこで、最初に次の行を作成します。
Copy Source | Copy HTML
- wchar_t * arr =(wchar_t *)malloc(1024); // 自由にすることを忘れないでください(arr);
- if (charged> = 0)
- _itow(有料、arr、10);
- 他に
- wcscpy(arr、L "?");
- wcscat(arr、L "%");
- if (!isOnBattery)wcscat(arr、L "(+)");
さらに、私は実際に再描画していると言うことを忘れないでください...
Copy Source | Copy HTML
- InvalidateRect(m_hwnd、&rc、 true );
次の2つのケースがあります-デスクトップコンポジションが有効かどうか。 なぜなら 私は古いWindowsテーマを使用せず、Aeroを好みます-コンポジションが無効になっている場合は、単にテキストを表示します:
Copy Source | Copy HTML
- SetBkColor(hdc、RGB(255、255、0));
- GetTextExtentPointW(hdc、arr、wcslen(arr)、およびサイズ );
- TextOutW(hdc、(RECTWIDTH(rc)- サイズ .cx)/ 2、(RECTHEIGHT(rc)- サイズ .cy)/ 2、arr、wcslen(arr));
含まれている構成の場合、もう少し複雑です:
Copy Source | Copy HTML
- DTTOPTS dttOpts = { sizeof (dttOpts)};
- dttOpts.dwFlags = DTT_COMPOSITED | DTT_TEXTCOLOR | DTT_GLOWSIZE;
- int red = 0 ;
- int green = 0 ;
- if (charged> 0 )
- {
- if (charged> 66 )green = 255 ;
- else if (charged> 33 )green = red = 255 ;
- それ以外の場合は赤= 255 ;
- }
- dttOpts.crText = RGB(赤、緑、 0 );
- dttOpts.iGlowSize = 10 ;
- DrawThemeTextEx(hTheme、hdcPaint、 0、0 、arr、-1、0、&rcText、&dttOpts);
実際、ここでは、どの色の電荷を描画するか(66-100%=緑、33-66%=黄色、0-33%=赤)を検討し、それぞれテキストを表示します。
それだけです。 プロジェクトをビルドできます。
ここでは、例にあるコードを示したのではなく、自分が変更または追加したコードのみを示したことに注意してください。
プロジェクトを正常にビルドした後、dllを取得しました。
COMコンポーネントおよび同様のマックを使用した私の経験に基づいて、結果のDLLを持つフォルダー内の管理者から次のコマンドを実行しました。
regsvr32 DeskbandSDKSample.dll
次に、コンテキストメニューから対応するパネルをオンにしました。
以上です。
ご質問は?