【C++/Win32】C# の SystemInformation が C++ のどれに該当するのかってやつ

C++
この記事は約15分で読めます。

C# の SystemInformation に慣れてしまった人向けです。毎回調べるのが面倒なのでシステム環境情報で使ったやつを記録していきます。C#は SystemInformation クラスから取得可能です。C++ は GetSystemMetrics か SystemParametersInfo から取得可能です。

対応表

C# のプロパティが C++ のどれを参照しているのかの対応表です。

C#C++内容
CaptionHeightSM_CYCAPTIONタイトルバー領域の高さ(ピクセル単位)23
MenuFontSPI_GETNONCLIENTMETRICSメニューに表示するテキストのフォント
MenuHeightSM_CYMENUメニューの 1 行の高さ (ピクセル単位) 21
MenuShowDelaySPI_GETMENUSHOWDELAYマウスオーバーでサブメニューが表示するまでの待機時間(ミリ秒)400

ソースコード

基本的に C# の SystemInformation クラス感覚で使えるようにしていきます。

class OTZSystemInformation {

public:
  /// <summary>
  /// 
  /// </summary>
  /// <param name="hWnd"></param>
  /// <returns></returns>
  static inline UINT GetMonitorDpi(HWND hWnd) {
    HMONITOR hMonitor = ::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
    // ディスプレイのDPIを取得する
    UINT dpiX = 96;
    UINT dpiY = 96;
    ::GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE::MDT_DEFAULT, &dpiX, &dpiY);
    return dpiY;
  }

  /// <summary>
  /// キーボードの繰り返し遅延設定を取得します。
  /// 値の範囲は、0 (約 250 ミリ秒の遅延) ~ 3 (約 1 秒の遅延) になります。
  /// </summary>
  /// <returns></returns>
  static inline int KeyBoardDelay(void) {
    int keyBoardDelay = 0;
    ::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &keyBoardDelay, 0);
    keyBoardDelay = keyBoardDelay * 250 + 250;
    return keyBoardDelay;
  }

  /// <summary>
  /// キーボードのリピート速度設定を取得します。
  /// 0 (1 秒に約 2.5 回の繰り返し) ~ 31 (1 秒に約 30 回の繰り返し) 
  /// </summary>
  /// <param name=""></param>
  /// <returns></returns>
  static inline int KeyBoardSpeed(void) {
    int keyBoardSpeed = 0;
    ::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &keyBoardSpeed, 0);
    return keyBoardSpeed;
  }

  /// <summary>
  /// ディスプレイ全体の情報を取得します
  /// </summary>
  /// <param name="hWnd"></param>
  /// <param name="rect"></param>
  static inline void GetMonitorRect(HWND hWnd, OTZRect& monitorRect) {
    HMONITOR monitor = ::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
    if (!monitor) {
      return;
    }

    MONITORINFOEX monitorInfo{};
    monitorInfo.cbSize = sizeof(monitorInfo);
    if (!::GetMonitorInfo(monitor, &monitorInfo)) {
      return;
    }
    monitorRect = monitorInfo.rcMonitor;
  }

  /// <summary>
  /// タスクバーを除いたディスプレイ情報を取得します
  /// </summary>
  /// <param name="hWnd"></param>
  /// <param name="rect"></param>
  static inline void GetMonitorWorkRect(HWND hWnd, OTZRect& monitorRect) {
    HMONITOR monitor = ::MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
    if (!monitor) {
      return;
    }

    MONITORINFOEX monitorInfo{};
    monitorInfo.cbSize = sizeof(monitorInfo);
    if (!::GetMonitorInfo(monitor, &monitorInfo)) {
      return;
    }
    monitorRect = monitorInfo.rcWork;
  }

  /// <summary>
  /// メニューの1行の高さ(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline int MenuHeight(void) {
    return ::GetSystemMetrics(SM_CYMENU);
  }

  /// <summary>
  /// 小さいアイコンのサイズ(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline OTZSize SmallIconSize(void) {
    return OTZSize(::GetSystemMetrics(SM_CXSMICON),
      ::GetSystemMetrics(SM_CYSMICON));
  }

  /// <summary>
  /// メニューバーボタンの既定の幅(ピクセル単位)とメニューバーの高さ(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline OTZSize MenuBarButtonSize(void) {
    NONCLIENTMETRICS ncm{};
    ::ZeroMemory(&ncm, sizeof(ncm));
    ncm.cbSize = sizeof(ncm);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
    return OTZSize(ncm.iMenuWidth, ncm.iMenuHeight);
  }

  /// <summary>
  /// メニューバーボタンの既定のサイズ(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline OTZSize MenuButtonSize(void) {
    return OTZSize(::GetSystemMetrics(SM_CXMENUSIZE),
      ::GetSystemMetrics(SM_CYMENUSIZE));
  }

  /// <summary>
  /// メニューのチェックマーク領域の既定のサイズ(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline OTZSize MenuCheckSize(void) {
    return OTZSize(::GetSystemMetrics(SM_CXMENUCHECK),
      ::GetSystemMetrics(SM_CYMENUCHECK));
  }

  /// <summary>
  /// タイトルバー領域の高さ(ピクセル単位)
  /// </summary>
  /// <returns></returns>
  static inline int CaptionHeight(void) {
    return ::GetSystemMetrics(SM_CYCAPTION);
  }

  /// <summary>
  /// マウスオーバーでサブメニューが表示するまでの待機時間(ミリ秒)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline DWORD MenuShowDelay(void) {
    DWORD time;
    ::SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &time, 0);
    return time;
  }

  /// <summary>
  /// マウスのポイント イベントを生成するために、マウス ポインターが収まっている必要のある
  /// 四角形の幅(ピクセル単位) を取得します。
  /// </summary>
  /// <returns></returns>
  static inline OTZSize MouseHoverSize(void) {
    int width;
    int height;
    ::SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH, 0, &width, 0);
    ::SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT, 0, &height, 0);
    return OTZSize(width, height);
  }

  /// <summary>
  /// ウィンドウのキャプションまたはタイトルバーのボタンを取得します。
  /// </summary>
  /// <returns></returns>
  static inline OTZSize CaptionButtonSize(void) {
    int width = ::GetSystemMetrics(SM_CXSIZE);
    int height = ::GetSystemMetrics(SM_CYSIZE);
    return OTZSize(width, height);
  }

  /// <summary>
  /// メニューに表示するテキストのフォントを取得します。
  /// </summary>
  /// <returns></returns>
  static inline HFONT MenuFont(void) {
    NONCLIENTMETRICS ncm{};
    ::ZeroMemory(&ncm, sizeof(ncm));
    ncm.cbSize = sizeof(ncm);
    ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
    return ::CreateFontIndirect(&ncm.lfMenuFont);
  }

  /// <summary>
  /// メニューに表示するテキストのフォントを取得します。
  /// </summary>
  /// <param name="dpi"></param>
  /// <returns></returns>
  static inline HFONT MenuFont(UINT dpi) {
    NONCLIENTMETRICS ncm{};
    ::ZeroMemory(&ncm, sizeof(ncm));
    ncm.cbSize = sizeof(ncm);
    ::SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0, dpi);
    return ::CreateFontIndirect(&ncm.lfMenuFont);
  }

  /// <summary>
  /// Windows のプログラム アイコンの既定のサイズ (ピクセル単位) を取得します。
  /// </summary>
  /// <param name="dpi"></param>
  /// <returns></returns>
  static inline OTZSize IconSize(UINT dpi = 96) {
    return OTZSize(
      ::GetSystemMetricsForDpi(SM_CXICON, dpi),
      ::GetSystemMetricsForDpi(SM_CYICON, dpi));
  }

  /// <summary>
  /// 小さいアイコンのサイズ (ピクセル単位) を取得します。
  /// </summary>
  /// <param name="size"></param>
  /// <returns></returns>
  static inline OTZSize SmallIconSize(UINT dpi = 96) {
    return OTZSize(
      ::GetSystemMetricsForDpi(SM_CXSMICON, dpi),
      ::GetSystemMetricsForDpi(SM_CYSMICON, dpi));
  }

  /// <summary>
  /// アイコンのフォントハンドルを取得します。
  /// </summary>
  /// <param name=""></param>
  /// <returns></returns>
  static inline HFONT IconFont(float size) {
    OTZFont iconFont(L"Segoe MDL2 Assets", size);
    LOGFONT l = iconFont.GetLogFont();
    return ::CreateFontIndirect(&l);
  }

  /// <summary>
  /// 垂直スクロールバーの幅(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline int VerticalScrollBarWidth(void) {
    return ::GetSystemMetrics(SM_CXVSCROLL);
  }

  /// <summary>
  /// 水平スクロールバーの高さ(ピクセル単位)を取得します。
  /// </summary>
  /// <returns></returns>
  static inline int HorizontalScrollBarHeight(void) {
    return ::GetSystemMetrics(SM_CXHSCROLL);
  }

  /// <summary>
  /// マウスに垂直スクロールホイールがあるかどうかを取得します。
  /// </summary>
  /// <param name=""></param>
  /// <returns></returns>
  static bool IsMouseWheelPresent(void) {
    if (!checkNativeMouseWheelSupport) {
      isMouseWheelSupport = (::GetSystemMetrics(SM_MOUSEWHEELPRESENT) != 0);
      checkNativeMouseWheelSupport = true;
    }
    return isMouseWheelSupport;
  }

  /// <summary>
  /// マウスホイールの移動量を取得します。
  /// </summary>
  /// <param name=""></param>
  /// <returns></returns>
  static inline int MouseWheelScrollLines(void) {
    int mouseWheelScrollLines = DefaultMouseWheelScrollLines;
    if (IsMouseWheelPresent()) {
      ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &mouseWheelScrollLines, 0);
    }
    return mouseWheelScrollLines;
  }

private:
  inline static bool checkNativeMouseWheelSupport = false;
  inline static bool isMouseWheelSupport = true;
  inline static const int DefaultMouseWheelScrollLines = 3;

};

コメント

タイトルとURLをコピーしました