| 
 スクリーンショットを取得したい - Kaneko -  05-29-2013
 
 Curlのアプリで、エラーが発生した際にスクリーンショットを送ってもらうことが、時々あるんですが、
 これをCurlのアプリ側でハンドリングすることはできないでしょうか?
 
 ①スクリーンショットを取得する(クリップボードでも、メモリ上でも、ファイルでも)
 ②特定のフォルダに吐き出す
 
 の処理ができれば嬉しいんですが、
 ActiveXで出来るのか?とも思ったんですが、ActiveXの情報の集め方がよくわからず、
 苦戦しています。
 
 よろしくお願いします。
 
 
 
 RE: スクリーンショットを取得したい - dyoshida -  05-31-2013
 
 Curlアプリのエラー状況のスクリーンショットに使えるか怪しい感もありますが
 試しにCurlで保存するコードを書いてみました。
 
 
 Code: || CurlのグラフィックをPNG形式のファイルに保存するプロシージャ{define-proc {save-root-graphic g:Graphic}:void
 || GraphicからPixmapを生成
 def pm = {Graphic-to-Pixmap g}
 
 || ImageDataを生成してPixmapを格納
 let img:ImageData = {ImageData}
 {img.pixmaps.append pm}
 
 || ファイル保存先のダイアログを表示
 {let file-url:#Url =
 {choose-file
 style = FileDialogStyle.save-as,
 title="Save screen shot",
 filters={{Array-of FileDialogFilter}
 {FileDialogFilter
 "PNG",
 {new
 {Array-of FileDialogTypeFilter},
 {FileDialogTypeFilter "png"}
 }
 }
 }
 }
 }
 
 || ImageDataをPNG形式で指定ファイルパスへ保存
 {if-non-null file-url then
 {img.save-to-url file-url, "image/png"}
 {popup-message "保存しました"}
 }
 }
 
 || スクリーンショットを取る領域の名前定義
 {def main-box-name = "main-box"}
 
 || 保存ボタン押下イベント
 {def on-save-button-event:EventHandler =
 {on Action at b:CommandButton do
 || ボタンから親をたどってスクリーンショットを取る領域のグラフィックを取得
 let grp:Graphic = b
 {while grp.parent != null do
 set grp = grp.parent
 {if grp.name == main-box-name then
 {break}
 }
 }
 || グラフィックを保存
 {save-root-graphic grp}
 }
 }
 
 || 画面表示
 {value
 {VBox name = main-box-name,
 halign="center",
 margin=2mm,
 {bold このアプリのスクリーンショットを保存},
 {Fill height = 2mm},
 {CommandButton
 label="スクリーンショット保存",
 on-save-button-event
 }
 }
 }
画面がリフレッシュされると直ってしまうエラーの場合は上記の方法だと駄目かもしれないので、
 その場合はスクリーンショットを取るActiveXコンポーネントを使った方がよいかもしれないですね。
 
 Windwos標準でもっているActiveX だと、WScript.Shell が使えそうなのですが、これで
 OSにALT + PrintScreenキーイベントを送ればクリップボードにスクリーンショットをとれるかとも
 思ったのですが、情報抜き取りの悪用を避けるためかPrintScreenキー送信は不可でした・・・
 
 他の方法も探してみます
 
 
 RE: スクリーンショットを取得したい - Kaneko -  05-31-2013
 
 試してみました。
 かなりいい!ですが、POPUPだったり、Viewだったりで複数のオブジェクトが表示されている場合があるので、
 あと一歩!(勝手に、評価してすいません)という印象でした。
 
 たしかにPrintScreenは渡せないみたいですね。
 ちょっと調べた範囲では、Excelを使った方法があるみたいですが
 http://d.hatena.ne.jp/language_and_engineering/20081121/1227203100
 
 これと同等のことをCurlからやる方法がイマイチわからず。。。
 
 CurlとActiveXを駆使すればなんでもできてしまいそうな反面、
 ActiveXとかWindowsの知識がシッカリしていないので、実装が難しいです。。。
 
 上のコードをCurlに変換して頂けませんか!
 期待してます。。。
 
 
 
 RE: スクリーンショットを取得したい - dyoshida -  05-31-2013
 
 ご指摘の通り、エラーが発生したときの状況把握という目的だとイマイチなのですよね・・・
 Curlだけで書いているのでプラットフォーム依存がないというメリットはあるのですが
 
 >ちょっと調べた範囲では、Excelを使った方法があるみたいですが
 
 Excelマクロの機能をつかってWin32APIのkeybd_event()でキーイベントを送信・・・
 なにかいろいろとレガシーな機能やAPIを使った方法のようなので、OSやExcelの
 バージョンによっては動かなくなりそうな裏技っぽい気もしますが、書いてみました。
 
 とりあえず、Windows7 pro(32bit) +Excel2007の環境ではこれで動作しました。
 
 Code: {import * from CURL.GRAPHICS.ACTIVEX}{import * from CURL.DESKTOP.CLIPBOARD}
 
 
 || WindowsへALT+PrintScreenキー押下イベントを送るプロシージャ
 {define-proc {send-alt-print-screen-key}:void
 def obj-excel =
 {ActiveXObject
 ProgId = "Excel.Application"
 }
 {obj-excel.ExecuteExcel4Macro( "CALL(\"user32\",\"keybd_event\",\"JJJJJ\",18, 0, 1,0)" )} || ALT press
 {obj-excel.ExecuteExcel4Macro( "CALL(\"user32\",\"keybd_event\",\"JJJJJ\",44, 0, 1,0)" )} || PrintScreen press
 {obj-excel.ExecuteExcel4Macro( "CALL(\"user32\",\"keybd_event\",\"JJJJJ\",44, 0, 3,0)" )} || PrintScreen release
 {obj-excel.ExecuteExcel4Macro( "CALL(\"user32\",\"keybd_event\",\"JJJJJ\",18, 0, 3,0)" )} || ALT release
 }
 
 || クリップボードの画像をPNG形式のファイルに保存するプロシージャ
 {define-proc {save-clip-board}:void
 || クリップボードを取得
 let cb:Clipboard = {Clipboard.get-system-clipboard}
 def cb-obj = {cb.get-object}
 
 || クリップボードから取得したPixmapをImageDataへ格納
 || Todo クリップボードから取得したオブジェクトがpixmapかチェックが必要
 let img:ImageData = {ImageData}
 {img.pixmaps.append (cb-obj asa Pixmap)}
 
 || ファイル保存先のダイアログを表示
 {let file-url:#Url =
 {choose-file
 style = FileDialogStyle.save-as,
 title="Save screen shot",
 filters={{Array-of FileDialogFilter}
 {FileDialogFilter
 "PNG",
 {new
 {Array-of FileDialogTypeFilter},
 {FileDialogTypeFilter "png"}
 }
 }
 }
 }
 }
 
 || ImageDataをPNG形式で指定ファイルパスへ保存
 {if-non-null file-url then
 {img.save-to-url file-url, "image/png"}
 {popup-message "保存しました"}
 }
 }
 
 || 保存ボタン押下イベント
 {def on-save-button-event:EventHandler =
 {on Action at b:CommandButton do
 || WindowsへALT+PrintScreenキー押下イベントを送る
 {send-alt-print-screen-key}
 || クリップボードに貼られたスクリーンショットを保存する処理をイベントキューへ積む
 || Todo
 ||  PrintScreenキーによるスクリーンショットのクリップボードへの貼り付けの完了待ちが
 ||  イベントキューへ積むだけで取れるのか不明なので念のため1s待って処理
 {after 1s do
 {save-clip-board}
 }
 }
 }
 
 || 画面表示
 {value
 {View
 visibility = "normal",
 {VBox
 halign="center",
 margin=2mm,
 {bold このアプリのスクリーンショットを保存},
 {Fill height = 2mm},
 {CommandButton
 label="スクリーンショット保存",
 on-save-button-event
 }
 },
 {on WindowClose do
 {exit}
 }
 }
 }
アクティブウィンドウをキャプチャするために、ALTキーのon/offを追加していますが、
 ディスクトップ全体をキャプチャしたい場合は"ALT press"/ ”ALT release”の
 コメントが付いている行を削ってください。
 
 とりあえず動きますという程度のコードですが、Curlでもこの技つかえましたね、
 ということでご参考まで。
 
 
 
 |