switch文でローカル変数を宣言する

2011年2月4日金曜日 | Published in | 6 コメント

このエントリーをはてなブックマークに追加

私はローカル変数をそれを使うコードの直前で定義する派(?)なのだが、switch文のケース内で定義ができなくていつも残念に思っていた。
今日ふと気がついてブロック { } で囲ってみた。

するとコンパイルが通った。
おお、これはいい。

#この既述が気持ち悪い人もいるかもね。

Responses

  1. shizaru says:
    2011年2月14日 21:13

    最新の記事にコメントをつけさせてもらおうと思ったら、すごい力作まとめの記事だったのでちょっと前の記事にコメントさせてもらいます。

    いつもSimpleCapにお世話になってます。また、「(旧)Cocoaの日々」の2008年初頭あたりの記事からじっくり読ませてもらって、プログラミングの勉強をしているため、もっぱらxcatsanさんは私にとって「師匠」にあたる存在であります。ここまでがごあいさつ。

    さて本題。CGWindowListCreateImage()だと、「アクティブでないSpacesのWorkspaceにあるアプリケーション」をキャプチャできない、が正解でしょうか。自作プログラムでどうしてもできないので、SimpleCapの「アプリケーション」メニューからキャプチャの動作を調べたところ、SimpleCapでもキャプチャできない現象が起きました。

    つまり、
    1,Spacesの「2」をアクティブにした状態で、
    2,Spacesの「1」にあるアプリを
    3,SimpleCapのメニューの「アプリケーション」からキャプチャしようとすると
    4,キャプチャに失敗する

    という現象です。これは私の環境(iMac27inch 2010late、OSX10.6.6)でだけの現象でありましょうか。

  2. shizaru says:
    2011年2月14日 21:13

    最新の記事にコメントをつけさせてもらおうと思ったら、すごい力作まとめの記事だったのでちょっと前の記事にコメントさせてもらいます。

    いつもSimpleCapにお世話になってます。また、「(旧)Cocoaの日々」の2008年初頭あたりの記事からじっくり読ませてもらって、プログラミングの勉強をしているため、もっぱらxcatsanさんは私にとって「師匠」にあたる存在であります。ここまでがごあいさつ。

    さて本題。CGWindowListCreateImage()だと、「アクティブでないSpacesのWorkspaceにあるアプリケーション」をキャプチャできない、が正解でしょうか。自作プログラムでどうしてもできないので、SimpleCapの「アプリケーション」メニューからキャプチャの動作を調べたところ、SimpleCapでもキャプチャできない現象が起きました。

    つまり、
    1,Spacesの「2」をアクティブにした状態で、
    2,Spacesの「1」にあるアプリを
    3,SimpleCapのメニューの「アプリケーション」からキャプチャしようとすると
    4,キャプチャに失敗する

    という現象です。これは私の環境(iMac27inch 2010late、OSX10.6.6)でだけの現象でありましょうか。

  3. xcatsan says:
    2011年2月15日 17:17

    こんにちは shizaru さん。
    橋口です。

    2008年初頭からというと旧ブログが始まって間もないころで、
    ちょうど SimpleCap 開発が始まる前ぐらいですね。
    ありがとうございますw

    さて質問の件ですが SimpleCap の場合、CGWindowListCreateImage() の
    第2引数に kCGWindowListOptionOnScreenOnly を指定しています。
    これが為に指摘された動きになっています。つまり Spaces で非アクティブな
    スクリーンにあるウィンドウは Off Screen 扱いになる為、上記
    オプション(On Screen Only)指定時にはキャプチャができません。

    なので、もし kCGWindowListOptionOnScreenOnly を指定している場合は
    それを外してみてください。Spaces で非アクティブなスクリーン上に
    あるウィンドウもキャプチャできると思います。

    #ただ Off Screen にあるウィンドウは見えないことをいいことに(?)
    #ちゃんと描画されていないかもしれません。この辺りは試したことが
    #無いのでちょっとわかりません。

    結果が出たら是非教えてくださいね。
    では。

  4. xcatsan says:
    2011年2月15日 17:17

    こんにちは shizaru さん。
    橋口です。

    2008年初頭からというと旧ブログが始まって間もないころで、
    ちょうど SimpleCap 開発が始まる前ぐらいですね。
    ありがとうございますw

    さて質問の件ですが SimpleCap の場合、CGWindowListCreateImage() の
    第2引数に kCGWindowListOptionOnScreenOnly を指定しています。
    これが為に指摘された動きになっています。つまり Spaces で非アクティブな
    スクリーンにあるウィンドウは Off Screen 扱いになる為、上記
    オプション(On Screen Only)指定時にはキャプチャができません。

    なので、もし kCGWindowListOptionOnScreenOnly を指定している場合は
    それを外してみてください。Spaces で非アクティブなスクリーン上に
    あるウィンドウもキャプチャできると思います。

    #ただ Off Screen にあるウィンドウは見えないことをいいことに(?)
    #ちゃんと描画されていないかもしれません。この辺りは試したことが
    #無いのでちょっとわかりません。

    結果が出たら是非教えてくださいね。
    では。

  5. shizaru says:
    2011年2月15日 19:16

    ど素人のくだらない質問に親切に答えていただいてありがとうございます。

    手元で試したところ、非アクティブなWorkspaceのアプリは第2引数になにを指定してもだめなようです。アクテイブなWorkspaceの該当rectをキャプチャするか、空のイメージしかできない模様。

    勉強になりました。ありがとうございました。早く新Cocoaの日々のお世話になれるよう、精進したいと思います。

  6. shizaru says:
    2011年2月15日 19:16

    ど素人のくだらない質問に親切に答えていただいてありがとうございます。

    手元で試したところ、非アクティブなWorkspaceのアプリは第2引数になにを指定してもだめなようです。アクテイブなWorkspaceの該当rectをキャプチャするか、空のイメージしかできない模様。

    勉強になりました。ありがとうございました。早く新Cocoaの日々のお世話になれるよう、精進したいと思います。

  7. xcatsan says:
    2011年2月16日 14:44

    shizaru さん、こんにちは。

    駄目でしたか。。
    私の方でも気になって SimpleCap をいじって少し試してみました。

    結果、できました。ただ SimpleCapでは CGWindowListCreateImage ではなく、
    CGWindowListCreateImageFromArray を使っています。


    SimpleCap のアプリケーションキャプチャは次のような動きになっています。

    1. CGWindowListCopyWindowInfo でウィンドウ一覧を取得
    2. タイマー起動
    3. カウント0になったら CGWindowListCreateImageFromArray で1.のウィンドウをキャプチャ


    CGWindowListCreateImageFromArray にはキャプチャしたいウィンドウの
    CGWindowID 配列を渡します。アプリケーションキャプチャの場合は、
    1. の CGWindowListCopyWindowInfo で一旦すべてのウィンドウの
    リストを取得した後、対象のアプリケーションのウィンドウだけに
    絞り込んでおきます。タイマー終了時にこれを 3 の関数へ渡して最終的なキャプチャ画像を
    作ります(実際には複数のイメージを重ねて加工していますが、基本は
    上記の動きです)。


    この 1. のCGWindowListCopyWindowInfoは次のような呼び出しになっています。
    CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListOptionOnScreenOnly|kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements), window_id);

    ここに昨日話しました kCGWindowListOptionOnScreenOnly を使っています。kCGWindowListOptionOnScreenBelowWindow も on screen 指定の一種ですね。

    そこで試しにそれらを外してリストを作るようにしてみました。

    CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListExcludeDesktopElements), window_id);

    するとアプリケーションキャプチャで非アクティブなワークスペース上にあるウィンドウをキャプチャすることができました。

    - - - -
    なお CGWindowListCreateImage の場合でも非アクティブなワークスペースにあるウィンドウの CGWIndowID が取れて"OnScreen"系のオプションを外せばキャプチャできるかもしれません。


    参考までに。
    では。

  8. xcatsan says:
    2011年2月16日 14:44

    shizaru さん、こんにちは。

    駄目でしたか。。
    私の方でも気になって SimpleCap をいじって少し試してみました。

    結果、できました。ただ SimpleCapでは CGWindowListCreateImage ではなく、
    CGWindowListCreateImageFromArray を使っています。


    SimpleCap のアプリケーションキャプチャは次のような動きになっています。

    1. CGWindowListCopyWindowInfo でウィンドウ一覧を取得
    2. タイマー起動
    3. カウント0になったら CGWindowListCreateImageFromArray で1.のウィンドウをキャプチャ


    CGWindowListCreateImageFromArray にはキャプチャしたいウィンドウの
    CGWindowID 配列を渡します。アプリケーションキャプチャの場合は、
    1. の CGWindowListCopyWindowInfo で一旦すべてのウィンドウの
    リストを取得した後、対象のアプリケーションのウィンドウだけに
    絞り込んでおきます。タイマー終了時にこれを 3 の関数へ渡して最終的なキャプチャ画像を
    作ります(実際には複数のイメージを重ねて加工していますが、基本は
    上記の動きです)。


    この 1. のCGWindowListCopyWindowInfoは次のような呼び出しになっています。
    CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListOptionOnScreenOnly|kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements), window_id);

    ここに昨日話しました kCGWindowListOptionOnScreenOnly を使っています。kCGWindowListOptionOnScreenBelowWindow も on screen 指定の一種ですね。

    そこで試しにそれらを外してリストを作るようにしてみました。

    CFArrayRef ar = CGWindowListCopyWindowInfo((kCGWindowListExcludeDesktopElements), window_id);

    するとアプリケーションキャプチャで非アクティブなワークスペース上にあるウィンドウをキャプチャすることができました。

    - - - -
    なお CGWindowListCreateImage の場合でも非アクティブなワークスペースにあるウィンドウの CGWIndowID が取れて"OnScreen"系のオプションを外せばキャプチャできるかもしれません。


    参考までに。
    では。

  9. shizaru says:
    2011年2月16日 20:02

    うわー、師匠の貴重な時間をとってもらってすみません。ていねいな説明ありがとうございます。私の場合は

    CFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll , kCGNullWindowID);

    で作ったリストを、
    if (CFDictionaryContainsKey(w, kCGWindowWorkspace))
    でオンスクリーンの証拠であるWorkspace番号があるもので絞り、取得したいアプリのPIDでウィンドウを検索してwindowIDを得て、

    CGImageRef cgimage = CGWindowListCreateImage(rect, kCGWindowListOptionIncludingWindow ,spot_window_id, kCGWindowImageDefault);

    としています。

    で、師匠の教えの通りに現在試行中ですが、やっぱ素人なのでまだ成功していません。もう少しがんばってみます。

  10. shizaru says:
    2011年2月16日 20:02

    うわー、師匠の貴重な時間をとってもらってすみません。ていねいな説明ありがとうございます。私の場合は

    CFArrayRef list =CGWindowListCopyWindowInfo( kCGWindowListOptionAll , kCGNullWindowID);

    で作ったリストを、
    if (CFDictionaryContainsKey(w, kCGWindowWorkspace))
    でオンスクリーンの証拠であるWorkspace番号があるもので絞り、取得したいアプリのPIDでウィンドウを検索してwindowIDを得て、

    CGImageRef cgimage = CGWindowListCreateImage(rect, kCGWindowListOptionIncludingWindow ,spot_window_id, kCGWindowImageDefault);

    としています。

    で、師匠の教えの通りに現在試行中ですが、やっぱ素人なのでまだ成功していません。もう少しがんばってみます。

  11. xcatsan says:
    2011年2月18日 6:42

    おはようございます。
    アプローチは間違ってないと思います。
    CGWindowListCopyWindowInfo で非アクティブな Workspace にあるウィンドウの WindowID が取れていればキャプチャできそうです。
    SimpleCap との違いは CGWindowListCreateImage を使っているか、CGWindowListCreateImageFromArray を使っているかの違いぐらいですね。
    原因はなんだろ。

  12. xcatsan says:
    2011年2月18日 6:42

    おはようございます。
    アプローチは間違ってないと思います。
    CGWindowListCopyWindowInfo で非アクティブな Workspace にあるウィンドウの WindowID が取れていればキャプチャできそうです。
    SimpleCap との違いは CGWindowListCreateImage を使っているか、CGWindowListCreateImageFromArray を使っているかの違いぐらいですね。
    原因はなんだろ。

Leave a Response

人気の投稿(過去 30日間)