はじめに
IkaLogの自動録画で使っているControlAmarecTV.au3にコードを追加して、AmaRecTVのフレーム無しウインドウのハンドルを取れるようにできたと思ったけど一定の条件で不具合が出るから結局ダメだったっぽいの続きになります。お約束をお読みになった上で、イカよろしくおねがいいたします。
・IkaLogさんのGitHubにコードが採用されました!(2016年6月9日追記)
余分なコードを除いてシンプルになっていますので、こちらをご覧ください。
せっかくここまで追加したのに、何か他の方法がないかなーと漠然と考えていたのですが、ウインド名以外で判定できれば大丈夫なのではとひらめきました。
調べたら、WinGetClassListというのを見つけました。
どんなのか、メッセージボックスに出しつつ調べると、AmaRecTVからは
msctls_statusbar32" & @LF & "Display" & @LF & "ToolbarWindow32" & @LF
というクラスリストが文字列になって取れるっぽくて、フレーム無しの時は "Display" & @LFだけになるっぽいです。
ウインドウ名に AmaRecTV という文字が含まれていて、クラスに Display が含まれてたら、それはもう AmaRecTV でいいですよね?
これでも、100%の判別にはならないかなー
その辺りが良くわからないのです……
実験に使用したコード
実際にIkaLogと連動させての動作確認は行っていません。
もしお使いになる場合は、事前に動作確認を行ってください。
テストの方法等は、ひとつ前の記事をご覧ください。
コードを表示するパーツのせいか、コードが変に化けているみたいなので、テキストファイルを用意しました。
(こちらをクリックしてください。)
※コードを表示するパーツをコピペで導入してるから、取り方が分からないのです…
; ; ; IkaLog ; ====== ; Copyright (C) 2015 Takeshi HASEGAWA ; ; Licensed under the Apache License, Version 2.0 (the 'License'); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an 'AS IS' BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; Start and stop recording using Open Broadcaster Software(OBS). ; ; To Start Recording: ; ControlAmarecTV.au3 start ; ; To Stop Recording: ; ControlAmarecTV.au3 stop ; ; To Reanem the recording: ; If you want to rename the recording to a specific filename, ; Specifcy the filename as environment variables ; IKALOG_MP4_DESTDIR and IKALOG_MP4_DESTNAME. ; ; Though this script will sleep seconds so that work on ; a specific environment. The behavior is subject to change. ; #include#include ; ;注意! ;コマンドプロンプトからの動作確認は行っていますが、IkaLogと連動させての確認はまだ行っていません。 ;もし利用される場合は、事前に動作確認を行ってタイミングの調整を行ってください。 ;自分の好みに合わせて値を設定してください。 ;Sendキーの詳しい書き方については https://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm Global $SendStartkeyValue = "{F8}" ;送信する録画開始キー Global $SendStopkeyValue = "{F9}" ;送信する録画終了キー Global $StartSleepSec = 0 ;録画開始待機時間(秒) Global $StopSleepSec = 8 ;録画終了待機時間(秒) Global $RenameSleepSec = 10 ;リネーム処理待機時間(秒) リネーム機能は使ってないので、値が正しいかわかりません。 Global $IniFileName = "ControlAmarecTV.exe" ;無視してください。 ;ウインドハンドル取得のサンプル動作用 Const $AmaChkTitle = "AmaRecTV" ;AmaRecTVハンドル取得用文字列 Const $AmaClassNF = "Display" & @LF ;AmaRecTV 3.10フレーム無し時のクラスリスト ;Const $AmaClass = "msctls_statusbar32" & @LF & "Display" & @LF & "ToolbarWindow32" & @LF ;AmaRecTV 3.10フレーム有り時のクラスリスト Func RenameFile($source) Local $dest = EnvGet('IKALOG_MP4_DESTNAME') $dest = StringReplace($dest, "/", "\") If $dest = '' Then Return False EndIf ; IkaLog assumes mp4 as video file extension, but AmarecTV uses avi. If StringRight($dest, 4) = ".mp4" Then $dest = StringReplace($dest, ".mp4", ".avi", -1) EndIf FileMove($source, $dest, $FC_OVERWRITE) EndFunc Func FindRecentRecording() ; Replace all slashes to backslashes. ; $directory also needs a backslash at its end. $directory = StringReplace($directory, "/", "\") If StringRight($directory, 1) <> "\" Then $directory = $directory & "\" EndIf Local $hSearch = FileFindFirstFile($directory & "*.avi*") If $hSearch = -1 Then MsgBox(0, "Error", "Could not find any candinates in " & $directory & " (path 1)", 10) Return False EndIf Local $latest_file = '' Local $latest_timestamp = '' While True Local $file = FileFindNextFile($hSearch) If @error Then ExitLoop Local $timestamp = FileGetTime($directory & $file, $FT_MODIFIED, $FT_STRING) If StringCompare($timestamp, $latest_timestamp) > 0 Then $latest_file = $directory & $file $latest_timestamp = $timestamp EndIf WEnd FileClose($hSearch) If $latest_file = '' Then MsgBox(0, "Error", "Could not find any candinates in " & $directory & " (path 2)", 10) Return False EndIf Return $latest_file EndFunc Func ControlAmarecTV($stop) Local $hWnd = WinWait('[CLASS:AmaRecTV; INSTANCE:2]', '', 1) If $hWnd = 0 Then MsgBox(0, "Error", "Could not find AmarecTV") Return False EndIf Local $text = ControlGetText($hWnd, "", "[CLASS:msctls_statusbar32]") Local $inRecording = StringInStr($text, '録画中...') > 0 ;問題は、フレーム無し時のウインドウハンドル値が異なる事だけだと気付く Local $hWndDsp = $hWnd ;テスト表示用 処理的には不要 Local $var = AmarecTVWinHandleValue() If ($var[0] <> "") And ($hWnd <> $var[1]) Then $hWnd = $var[1] EndIf Local $click = False If $inRecording and $stop Then ;Stop Recording. $click = True ElseIf (Not $inRecording) and (Not $stop) Then ; Start Recording. $click = True EndIf If $click Then If $stop Then ; 録画終了待ち時間 Sleep(1000 * $StopSleepSec) Else ; 録画開始待ち時間 Sleep(1000 * $StartSleepSec) EndIf WinActivate($hWnd) WinWaitActive($hWnd, "", 1) If $stop Then ; 録画停止キー送る Send($SendStopkeyValue) Else ; 録画開始キー送る Send($SendStartkeyValue) EndIf If $stop Then Local $directory = EnvGet('IKALOG_MP4_DESTDIR') If (StringLen($directory) <> 0) Then Sleep(1000 * $RenameSleepSec) Local $file = FindRecentRecording() RenameFile($file) EndIf EndIf EndIf ;MsgBox(0, $var[0] , $hWndDsp & @LF & $hWnd & @LF & $var[1] & @LF & $text , 5) ;テスト表示 EndFunc ;AmarecTVのハンドルとウインドタイトルを取得する(サンプルコードをそのまま流用) ;AmaRecTVに含まれるクラス名が含まれてたらAmaRecTVと認識するようにしました。 ;http://open-shelf.appspot.com/AutoIt3.3.6.1j/html/functions/WinList.htm Func AmarecTVWinHandleValue() Local $var = WinList() Local $retValue[2] $retValue[0] = "" ;ウインドウタイトル $retValue[1] = 0 ;ウインドウハンドル For $i = 1 to $var[0][0] ; 可視で名前のあるウィンドウのみ If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then ;MsgBox(64, "Details", "Title=" & $var[$i][0] & @LF & "Handle=" & $var[$i][1], 10) ;MsgBox(64, $var[$i][0] , "ClassList=" & WinGetClassList($var[$i][0]), 10) ;AmaRecTVを探す If (StringInStr($var[$i][0], $AmaChkTitle)) Then ;タイトルに AmaRecTVが含まれる If (StringInStr(WinGetClassList($var[$i][0]), $AmaClassNF)) Then ;Display $retValue[0] = $var[$i][0] $retValue[1] = $var[$i][1] Return $retValue EndIf EndIf EndIf Next Return $retValue EndFunc Func IsVisible($handle) If BitAnd( WinGetState($handle), 2 ) Then Return 1 Else Return 0 EndIf EndFunc ;AmarecTVの枠表示の状態を確認 Func AmarecTVHandleMonitor() Local $var = AmarecTVWinHandleValue() Local $title = $var[0] Local $hWnd = $var[1] If $hWnd = 0 Then MsgBox(0, "取得できた情報", "AmarecTV いないっぽい。") Return False EndIf Local $text = ControlGetText($hWnd, "", "[CLASS:msctls_statusbar32]") If ($text = "") Then Local $ident = "枠なしっぽい?" Else $ident = "□枠ありっぽい!□" EndIf Local $hCnd = ControlGetHandle($hWnd, "", "[CLASS:msctls_statusbar32]") Local $hWndIka = WinWait('[CLASS:AmaRecTV; INSTANCE:2]', '', 1) ;オリジナルのハンドル取得 Local $textIka = ControlGetText($hWnd, "", "[CLASS:msctls_statusbar32]") ;オリジナルの文字列取得 $msg = StringFormat("ウインドウタイトル: %s%s", $title, @LF) $msg = StringFormat("%sオリジナルのハンドル: %s%s", $msg, $hWndIka, @LF) $msg = StringFormat("%sサンプルのハンドル : %s%s", $msg, $hWnd, @LF) $msg = StringFormat("%sオリジナルで取れる値: %s%s", $msg, $textIka, @LF) $msg = StringFormat("%sウインド下部の文字列: %s%s", $msg, $text, @LF) $msg = StringFormat("%sウインド下部の文字列を表示しているコントロールのハンドル: %s%s", $msg, $hCnd, @LF) $msg = StringFormat("%s枠の判定: %s", $msg, $ident) MsgBox(0, "取得できた情報", $msg) EndFunc ;main ;スクリプトの設置先を取得(無視してください) $IniFileName = StringFormat("%s", @ScriptFullPath) ;オプション無しで起動した時は、使い方と現在のiniの値を表示する。 if ($CmdLine[0] = 0) Then Local $title = "起動オプションが必要です" Local $msg = StringFormat("%s%s", "--- 使い方---", @LF) $msg = StringFormat("%s%s%s%s%s",$msg, "録画開始:", @ScriptFullPath, " start", @LF) $msg = StringFormat("%s%s%s%s", $msg, "録画終了:", @ScriptFullPath, " stop" & @LF & @LF) $msg = StringFormat("%s%s%s", $msg, "--- 現在の設定 --- ", @LF) $msg = StringFormat("%s%s%s%s", $msg, "スクリプトの設置パス: ", $IniFileName, @LF) $msg = StringFormat("%s%s%s%s", $msg, "録画開始キー: ", $SendStartkeyValue, @LF) $msg = StringFormat("%s%s%s%s", $msg, "録画終了キー: ", $SendStopkeyValue, @LF) $msg = StringFormat("%s%s%s%s", $msg, "録画開始待ち秒: ", $StartSleepSec, @LF) $msg = StringFormat("%s%s%s%s", $msg, "録画終了待ち秒: ", $StopSleepSec, @LF) $msg = StringFormat("%s%s%s%s", $msg, "リネーム待ち秒: ", $RenameSleepSec, @LF) $msg = StringFormat("%s%s", $msg, @LF) $msg = StringFormat("%s%s%s", $msg, "[はい]を押すと何もせずこのまま終了します。", @LF) $msg = StringFormat("%s%s%s", $msg, "[いいえ]を押すと表示中のウインドからAmaRecTVを探す処理を実行します。", @LF) If (MsgBox(4+64, $title, $msg, 60) = 7) Then AmarecTVHandleMonitor() EndIf Else $stop = StringCompare($CmdLine[1], 'stop') == 0 ControlAmarecTV($stop) EndIf
古い情報かも知れませんが、AmaRecTVって最小化してたらCPU負荷が下がるらしいです。