Post Reply 
 
Thread Rating:
  • 72 Votes - 2.65 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PCで現在のOSのアイドル時間情報を知る方法
01-04-2016, 03:35 PM
Post: #1
PCで現在のOSのアイドル時間情報を知る方法
Curlでメッセンジャーアプリを開発しています。

ユーザーがメッセンジャーを使用する時に、一定時間の間何も操作をしなかった場合(席の外す時など)
「不在中..」という状態情報をメッセンジャー画面に表示したいんです。
このような場合にCurlで、現在のOS(WindowsまたはMac OS)の無効時間情報を知る方法が何ですか?

御存じの方がいらっしゃれば教えていただければ幸いです。
Find all posts by this user
Quote this message in a reply
01-06-2016, 12:39 PM
Post: #2
RE: PCで現在のOSのアイドル時間情報を知る方法
Curlアプレットのウィンドウ内部に対する操作でしたら、get-gui-manager(プロシージャ)を使用して取得した
GuiManagerにKeyPressとPointerEventのイベントハンドラを追加して監視できそうですが、直接OSから
取得するとなると難しそうですね。

WindowsではCURL.LANGUAGE.DLL-INTERFACEを使用して、user32.dllのget-last-input-infoと
Kernel32.dllのget-tick-countを呼び出せばOSが持っているユーザが最後に入力した時刻からの
経過時間が計算できると思います。(残念ながらMac OSはよくわかりません)

試しにコードを書いてみましたが、こんな感じでしょうか。
Code:
{curl 8.0 applet}
{curl-file-attributes character-encoding = "utf8"}

{import * from CURL.LANGUAGE.DLL-INTERFACE}

{def
    UINT = int,
    DWORD = int32,
    BOOL = int
}

|| GetLastInputInfo関数の引数に指定するLASTINPUTINFO 構造体へのインターフェイス定義
|| see. https://msdn.microsoft.com/en-us/library/windows/desktop/ms646272.aspx
{define-C-struct public LASTINPUTINFO
  field public cbSize:UINT
  field public dwTime:DWORD
  def public size-of = 8 || sizeof LASTINPUTINFO
}

|| user32.dllのget-last-input-info関数を使用するための特別クラスの定義
|| see. https://msdn.microsoft.com/en-us/library/windows/desktop/ms646302.aspx
{define-dll-class public User32Dll
  {defaults
      calling-convention = stdcall,
      string-rep = CStringUTF16
  }
  
  {constructor public {default}
      {construct-super {SharedLibrary "user32.dll"}}
  }
  
  {dll-method public {get-last-input-info ("GetLastInputInfo")
                         pii:CPointer
                     }:BOOL
  }
}

|| Kernel32.dllのget-tick-count関数を使用するための特別クラスの定義
|| see. https://msdn.microsoft.com/en-us/library/ms724408.aspx
{define-dll-class public Kernel32Dll
  {defaults
      calling-convention = stdcall,
      string-rep = CStringUTF16
  }
  
  {constructor public {default}
      {construct-super {SharedLibrary "Kernel32.dll"}}
  }
  
  {dll-method public {get-tick-count ("GetTickCount")}:DWORD}
}


|| ユーザが最後に入力した時刻からの経過時間を取得するプロシージャ
{define-proc public {get-last-input-time}:int
    def user32 = {User32Dll}
    def kernel32 = {Kernel32Dll}
    def info = {LASTINPUTINFO}
    set info.cbSize = LASTINPUTINFO.size-of
    
    def ret = {user32.get-last-input-info
                  info
              }
    {if ret == 0 then
        || failure
        {error {get-last-win32-error}}
    }
    
    def tick = {kernel32.get-tick-count}
    def elapsed-time = tick - info.dwTime

    {return elapsed-time}
}

|| 表示
{value
    def td-time = {TextDisplay
                      width = 2cm,
                      halign = "right"
                  }

    {Frame
        {HBox
            "最後の入力からの経過時間",
            td-time,
            "ms"
        },
        {on e:AttachEvent at f:Frame do
            {Timer
                interval=1s,
                {on TimerEvent do
                    def time = {get-last-input-time}
                    set td-time.value = {String time}
                }
            }
        }
    }
}
Find all posts by this user
Quote this message in a reply
01-06-2016, 03:06 PM
Post: #3
RE: PCで現在のOSのアイドル時間情報を知る方法
早速のご回答ありがとうございます。
サンプルのソースコードまで作成して頂き、さらにありがとうございます。
ご助言頂きました様に一度試してみます。
Find all posts by this user
Quote this message in a reply
01-07-2016, 10:10 AM (This post was last modified: 01-07-2016 10:13 AM by Sanchez Chung.)
Post: #4
RE: PCで現在のOSのアイドル時間情報を知る方法
前のメールで頂いたサンプルのソースコードに対して
もう一つのご意見をいただければと思います。
コードは下の部分です

{define-C-struct public LASTINPUTINFO
field public cbSize:UINT
field public dwTime:DWORD
def public size-of = 8 || sizeof LASTINPUTINFO
}

このコードの四番目のラインである、
def public size-of = 8 || sizeof LASTINPUTINFO ...で、
「size-of = 8」とあらかじめ設定して置いてあるんですが、
これを動的にCurlで知る(取得する)ことは出来るかどうかという質問です。

お手数になるかもしれないんですが
よろしくお願いいたします。
Find all posts by this user
Quote this message in a reply
01-08-2016, 05:54 PM
Post: #5
RE: PCで現在のOSのアイドル時間情報を知る方法
Win32 API で定義されているLASTINPUTINFO構造体のサイズをCurlから動的に取得する
よいアイディアは残念ながら思いつきません。

とりあえず、8がマジックナンバーにならないように下記のように書くと少し良くなるかもしれませんが
悩ましいですね
Code:
def public Win32-UINT-size = 4
def public Win32-DWORD-size = 4

def public size-of = Win32-UINT-size + Win32-DWORD-size || sizeof LASTINPUTINFO
Find all posts by this user
Quote this message in a reply
01-11-2016, 09:51 AM (This post was last modified: 01-11-2016 09:55 AM by Sanchez Chung.)
Post: #6
RE: PCで現在のOSのアイドル時間情報を知る方法
御高見いただいて
どうもありがとうございました。

今までのアドバイスされたコードは
非常に助かります。
誠にありがとうございます。
Find all posts by this user
Quote this message in a reply
Post Reply 

Forum Jump:


User(s) browsing this thread:
1 Guest(s)