# | チョコグラフ名 | 発見場所 | スクリーンショット |
1 | 川のほとり | チョコボの森1 | |
2 | 山のはざま | チョコボの森1 | |
3 | みかいの地 | チョコボの森1 | |
4 | やすらぎの浜 | チョコボの森1 | |
5 | 枯れた砂浜 | チョコボの森1 | |
6 | いてつく大地 | チョコボの森1 | |
7 | 忘れられた浅瀬 | チョコボの入り江1 | |
8 | 遠くの浅瀬 | チョコボの森1 | |
9 | 枯れ果てゆく浅瀬 | チョコボの入り江1 | |
10 | ふかんの浅瀬 | チョコボの森1 | |
11 | 小さな浜辺 | チョコボの森1 | |
12 | 夜あけの浅瀬 | チョコボの入り江1 | |
13 | 閉ざされた森 | チョコボの森2 | |
14 | 緑の高原 | チョコボの森2 | |
15 | 夕ぐれの高原 | チョコボの入り江1 | |
16 | 忘れられた高原 | チョコボの森2 | |
17 | 夕ぐれの海原 | チョコボの入り江2 | |
18 | 海 | チョコボの入り江2 | |
19 | 冷たい入り江 | チョコボの森2 | |
20 | 霧の近海 | チョコグラフのかけら(入り江2だった) | |
21 | 外側の島 | チョコボの空中庭園 | |
22 | 外側の島2 | チョコボの入り江2 | |
23 | せいれいの島 | チョコボの空中庭園 | |
24 | 忘れられた島 | チョコボの空中庭園 |
ファイナルファンタジーXI(FF9) DISC4(4章)で買える武器・合成アイテム一覧
武器・防具
アイテム名 | 値段 | 売っている場所 | ||
ミスリルダガー | 950 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
グラディウス | 2300 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
アイスブランド | 3780 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
パルチザン | 1600 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
アイスランス | 2430 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
猫の爪 | 4000 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ポイズンナックル | 5000 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | イプセンの古城・モグネット |
星くずのロッド | 760 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
いやしのロッド | 1770 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ラミアのふえ | 3800 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | イプセンの古城・モグネット |
炎のつえ | 1100 | アレクサンドリア城下町・広場の武器屋 | ||
氷のつえ | 980 | アレクサンドリア城下町・広場の武器屋 | ||
雷のつえ | 1200 | アレクサンドリア城下町・広場の武器屋 | ||
オークスタッフ | 2400 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | イプセンの古城・モグネット |
円月輪 | 200 | アレクサンドリア城下町・広場の武器屋 | ||
ガラスの腕輪 | 250 | アレクサンドリア城下町・広場の武器屋 | ||
ボーンリスト | 330 | アレクサンドリア城下町・広場の武器屋 | ||
ミスリルの腕輪 | 500 | アレクサンドリア城下町・広場の武器屋 | ||
魔法の腕輪 | 1000 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | ダゲレオ・武器屋 |
ミスリルのこて | 980 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
雷神のこて | 1200 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ラミアのティアラ | 800 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | ダゲレオ・武器屋 |
みこしかつぎ帽子 | 1000 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
みじりはちまき | 1200 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
バルビュータ | 600 | アレクサンドリア城下町・広場の武器屋 | ||
ミスリルヘルム | 1000 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ゴールドヘルム | 1800 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
魔術師の服 | 1850 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
サバイバルベスト | 2900 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ブリガンダイン | 4300 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ミスリルアーマー | 1830 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
プレイトメイル | 2320 | アレクサンドリア城下町・広場の武器屋 | トレノ・武器屋 | |
ダガー | 320 | トレノ・武器屋 | ||
メイジマッシャー | 500 | トレノ・武器屋 | イプセンの古城・モグネット | |
さんごの剣 | 4000 | トレノ・武器屋 | ||
マルチナラケット | 750 | トレノ・武器屋 | イプセンの古城・モグネット | |
リネンキュラッサ | 800 | トレノ・武器屋 | ||
オリハルコン | 17000 | ダゲレオ・武器屋 | ||
ディフェンダー | 9340 | ダゲレオ・武器屋 | ||
アルテマソード | 14000 | ダゲレオ・武器屋 | ||
ホーリーランス | 11000 | ダゲレオ・武器屋 | ||
アベンジャー | 16000 | ダゲレオ・武器屋 | ||
カイザーナックル | 18000 | ダゲレオ・武器屋 | ||
ミスリルラケット | 2250 | ダゲレオ・武器屋 | ||
フォーク | 1100 | ダゲレオ・武器屋 | ||
ビストロフォーク | 10300 | ダゲレオ・武器屋 | ||
ライジングサン | 500 | ダゲレオ・武器屋 | イプセンの古城・モグネット | |
エゴイストの腕輪 | 2000 | ダゲレオ・武器屋 | ||
ドラゴンリスト | 4800 | ダゲレオ・武器屋 | ||
パワーリスト | 5100 | ダゲレオ・武器屋 | ||
まもりのこて | 6000 | ダゲレオ・武器屋 | ||
イージスのこて | 7000 | ダゲレオ・武器屋 | ||
魔術師の帽子 | 600 | ダゲレオ・武器屋 | ||
金の髪飾り | 3700 | ダゲレオ・武器屋 | イプセンの古城・モグネット | |
ヒュプノクラウン | 4400 | ダゲレオ・武器屋 | ||
閃光魔帽 | 5200 | ダゲレオ・武器屋 | ||
アダマン帽 | 6100 | ダゲレオ・武器屋 | ||
プラチナヘルム | 4600 | ダゲレオ・武器屋 | ||
カエサルヘルム | 7120 | ダゲレオ・武器屋 | ||
魔人の胸当て | 10250 | ダゲレオ・武器屋 | ||
ミネルバビスチェ | 12200 | ダゲレオ・武器屋 | ||
忍びの衣 | 14000 | ダゲレオ・武器屋 | ||
プラチナアーマー | 10500 | ダゲレオ・武器屋 | ||
キャラビニエール | 12300 | ダゲレオ・武器屋 | ||
ドラゴンメイル | 14000 | ダゲレオ・武器屋 | ||
アイアンソード | 660 | イプセンの古城・モグネット | ||
ミスリルスピア | 1100 | イプセンの古城・モグネット | ||
ミスリルロッド | 560 | イプセンの古城・モグネット | ||
ニードルフォーク | 3100 | イプセンの古城・モグネット | ||
ンカイの腕輪 | 3000 | イプセンの古城・モグネット | ||
ヒスイの腕輪 | 3400 | イプセンの古城・モグネット | ||
ベネチアシールド | 2800 | イプセンの古城・モグネット | ||
レッドキャップ | 3000 | イプセンの古城・モグネット | ||
クロスヘルム | 2200 | イプセンの古城・モグネット | ||
ダイヤヘルム | 3000 | イプセンの古城・モグネット | ||
力だすき | 7200 | イプセンの古城・モグネット | ||
大地の衣 | 8700 | イプセンの古城・モグネット | ||
シールドアーマー | 4300 | イプセンの古城・モグネット | ||
デモンズメイル | 5900 | イプセンの古城・モグネット | ||
ウィザードロッド | 3990 | 黒魔道士の村 | ||
セイレーンのふえ | 7000 | 黒魔道士の村 | ||
魔導師のつえ | 6000 | 黒魔道士の村 | ||
シーフの帽子 | 7100 | 黒魔道士の村 | ||
司祭の帽子 | 8300 | 黒魔道士の村 | ||
黒装束 | 16300 | 黒魔道士の村 |
合成屋
アイテム名 | 値段 | 素材1 | 素材2 | 売っている場所 | |||
エンジェルブレス | 9000 | ミスリルダガー | グラディウス | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 |
サルガタナス | 12000 | グラディウス | ゾーリンシェイプ | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
もめんのローブ | 1000 | リスト | とんがり帽子 | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
シルクのローブ | 2000 | シルクの服 | バンダナ | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
魔術師のローブ | 3000 | 魔道士のつえ | 魔術師の服 | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | ||
飽食のローブ | 6000 | ミスリルフォーク | もめんのローブ | ダゲレオ・合成屋 | |||
白のローブ | 8000 | 大地の衣 | ヒスイの腕輪 | ダゲレオ・合成屋 | |||
黒のローブ | 8000 | 大地の衣 | ンカイの腕輪 | ダゲレオ・合成屋 | |||
カチューシャ | 1000 | 三角帽子 | ラバーヘルム | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
さんごの指輪 | 1200 | 雷のつえ | ロッド | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
魔術師のくつ | 1500 | ゲルミナスブーツ | ボーンリスト | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
バレッタ | 1800 | ニードルフォーク | バルビュータ | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
パワーベルト | 2000 | ガラスのバックル | チェインメイル | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
マダインの指輪 | 3000 | ボーンリスト | 星くずのロッド | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
妖精のピアス | 3200 | 魔法の腕輪 | 金の針 | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
イクステンション | 3500 | ラミアのティアラ | マルチナラケット | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
リフレクトリング | 7000 | アンクレット | マダインの指輪 | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
アンクレット | 4000 | 金のチョーカー | ペリドット | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
フェザーブーツ | 4000 | 魔術師のくつ | フェニックスの羽 | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
黒帯 | 4000 | ねじりはちまき | サバイバルベスト | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
パールルージュ | 5000 | ムーンストーン | エリクサー | ダゲレオ・合成屋 | アレクサンドリア・合成屋 | トレノ・合成屋 | |
プロミストリング | 6000 | キマイラの腕輪 | ルビー | ダゲレオ・合成屋 | |||
バトルブーツ | 6500 | フェザーブーツ | ウイングエッジ | ダゲレオ・合成屋 | |||
転生の指輪 | 7000 | ダイヤモンド | アンクレット | ダゲレオ・合成屋 | |||
天使のイヤリング | 8000 | 妖精のピアス | バレッタ | ダゲレオ・合成屋 | |||
ガーネット | 350 | 原石 | 万能薬 | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
アメジスト | 200 | 原石 | 迷惑チン | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
ペリドット | 100 | 原石 | 金の針 | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
サファイア | 200 | 原石 | 毒消し | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
オパール | 100 | 原石 | ポーション | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
トパーズ | 100 | 原石 | 目薬 | ダゲレオ・合成屋 | 黒魔道士の村・合成屋 | ||
盗賊のこて | 50000 | ミスリルの腕輪 | サルガタナス | ダゲレオ・合成屋 | |||
オーガニクス | 700 | メイジマッシャー | メイジマッシャー | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
エクスプローダ | 1000 | メイジマッシャー | ミスリルダガー | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
ルーントゥース | 2000 | ミスリルダガー | ミスリルダガー | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
デザートブーツ | 300 | 皮の帽子 | 皮の服 | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
黄色いスカーフ | 400 | 羽根付き帽子 | とんがり帽子 | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
ガラスのバックル | 500 | ガラスの腕輪 | 皮のリスト | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
ゲルミナスブーツ | 900 | デザートブーツ | フォーク | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
金のチョーカー | 1300 | リネンキュラッサ | 金の針 | アレクサンドリア・合成屋 | トレノ・合成屋 | 黒魔道士の村・合成屋 | |
バタフライソード | 300 | ダガー | メイジマッシャー | 黒魔道士の村・合成屋 | |||
マサムネ | 16000 | ゾーリンシェイプ | オリハルコン | 黒魔道士の村・合成屋 | |||
デュエルクロー | 16000 | ドラゴンクロー | タイガーファング | 黒魔道士の村・合成屋 | |||
司祭のラケット | 11000 | エアラケット | カチューシャ | 黒魔道士の村・合成屋 | |||
ブレイサー | 24000 | グラディウス | ゾーリンシェイプ | 黒魔道士の村・合成屋 | |||
ガントレット | 8000 | ミスリルのこて | ドラゴンリスト | 黒魔道士の村・合成屋 | |||
黄金のスカラー | 15000 | ゴールドヘルム | 金の髪飾り | 黒魔道士の村・合成屋 | |||
サークレット | 20000 | ヒュプノクラウン | ロゼッタの腕輪 | 黒魔道士の村・合成屋 | |||
グランドヘルム | 20000 | クロスヘルム | パワーベルト | 黒魔道士の村・合成屋 | |||
ラバーコンシャス | 20000 | ミネルバビスチェ | エゴイストの腕輪 | 黒魔道士の村・合成屋 | |||
ブレイブスーツ | 26000 | ミスリルベスト | ミスリルロッド | 黒魔道士の村・合成屋 | |||
光のローブ | 20000 | 魔術師のローブ | ガラスの腕輪 | 黒魔道士の村・合成屋 | |||
グランドアーマー | 45000 | ミスリルソード | ミスリルアーマー | 黒魔道士の村・合成屋 | |||
エルメスのくつ | 12000 | バトルブーツ | エメラルド | 黒魔道士の村・合成屋 | |||
ロゼッタの指輪 | 24000 | マダインの指輪 | ホーリーランス | 黒魔道士の村・合成屋 | |||
ラピスラズリ | 400 | 原石 | デッドペッパー | 黒魔道士の村・合成屋 |
C# DirectShowで動画を再生する方法
当方Windows 10でVisual Studio Community 2019を使用しています。
参照の追加
C#のプロジェクトを右クリック→追加→COM参照を選択します。
[ActiveMovie control type library]にチェックを入れ、OKを押します。
もしActiveMovie control type libraryが存在しない場合などは次の方法でdllを追加してください。
[参照]→[参照]ボタン→C:\Windows\System32\quartz.dllを選択して、③が追加されたことを確認します。
必要なパッケージ
using QuartzTypeLib;
コード
C#でフォームアプリケーションでプロジェクトを作成します。
GUI
デザイナーで以下のコンポーネントを追加します。
・Panel (名前:panel1)
・Button (名前:button1)
ここでは、ボタンを押すとpanelに動画が再生されるようにコードを書きます。
C#のコード
private FilgraphManager objFilterGraph = null; private IBasicAudio objBasicAudio = null; private IVideoWindow objVideoWindow = null; private IMediaEvent objMediaEvent = null; private IMediaEventEx objMediaEventEx = null; private IMediaPosition objMediaPosition = null; private IMediaControl objMediaControl = null; private const int WM_APP = 0x8000; private const int WM_GRAPHNOTIFY = WM_APP + 1; private const int EC_COMPLETE = 0x01; private const int WS_CHILD = 0x40000000; private const int WS_CLIPCHILDREN = 0x2000000; enum MediaStatus { None, Stopped, Paused, Running }; private MediaStatus currentStatus = MediaStatus.None; private void button1_Click(object sender, EventArgs e) { objFilterGraph = new FilgraphManager(); // ここに固定で再生したい動画ファイルのフルパスを書く objFilterGraph.RenderFile(@"C:\temp\midori.avi"); objBasicAudio = objFilterGraph as IBasicAudio; objBasicAudio.Volume = -1000; // 音量を少し下げておく try { objVideoWindow = objFilterGraph as IVideoWindow; objVideoWindow.Owner = (int)panel1.Handle; objVideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN; objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left, panel1.ClientRectangle.Top, panel1.ClientRectangle.Width, panel1.ClientRectangle.Height); } catch (Exception ex) { objVideoWindow = null; } objMediaEvent = objFilterGraph as IMediaEvent; // メッセージの傍受 DirectShowを親ウィンドウに送信します objMediaEventEx = objFilterGraph as IMediaEventEx; objMediaEventEx.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, 0); // ビデオまたはオーディオトラックを開始および停止する objMediaControl = objFilterGraph as IMediaControl; // 再生開始 objMediaControl.Run(); currentStatus = MediaStatus.Running; }
フォーム終了時などに実行する解放処理は以下の通りです。
if (objMediaControl != null) { objMediaControl.Stop(); } currentStatus = MediaStatus.Stopped; if (objMediaEventEx != null) { objMediaEventEx.SetNotifyWindow(0, 0, 0); } if (objVideoWindow != null) { objVideoWindow.Visible = 0; objVideoWindow.Owner = 0; } if (objMediaControl != null) objMediaControl = null; if (objMediaPosition != null) objMediaPosition = null; if (objMediaEventEx != null) objMediaEventEx = null; if (objMediaEvent != null) objMediaEvent = null; if (objVideoWindow != null) objVideoWindow = null; if (objBasicAudio != null) objBasicAudio = null; if (objFilterGraph != null) objFilterGraph = null;
一時停止する場合は以下のコードを実行します。
objMediaControl.Pause();
一時停止を再開する場合は以下のコードを実行します。
objMediaControl.Run();
動画を末尾まで再生したことを検知して止めるためのコードは以下の通りです。
メッセージプロシージャをオーバーライドして特定のメッセージだけ処理を追加する形にしています。
protected override void WndProc(ref Message m) { if (m.Msg == WM_GRAPHNOTIFY) { int lEventCode; int lParam1, lParam2; while (true) { try { objMediaEventEx.GetEvent(out lEventCode, out lParam1, out lParam2, 0); objMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2); if (lEventCode == EC_COMPLETE) { objMediaControl.Stop(); objMediaPosition.CurrentPosition = 0; currentStatus = MediaStatus.Stopped; } } catch (Exception) { break; } } } base.WndProc(ref m); }
トラックバー(シークバー)の設置
どうせなのでトラックバーも設置してしまいましょう。
トラックバー設置により、再生位置をクリックしたりドラッグしたりして、好きな位置に飛べるようにします。
GUIの設置
デザイナ画面でTrackbarを設置します。変数名はデフォルトのtrackBar1とします。
コード
button1_Click関数で再生を開始するときにトラックバーの設定コードを追加します。
まずトラックバーの取りうる値をMinimumとMaximumに設定します。
ここでは動画の秒数をMaximumに設定します。
private void button8_Click(object sender, EventArgs e) { : // 再生開始 objMediaControl.Run(); currentStatus = MediaStatus.Running; // トラックバーの設定 this.trackBar1.Minimum = 0; this.trackBar1.Maximum = (int)objMediaPosition.Duration; this.trackBar1.Value = 0; this.trackBar1.TickFrequency = 1;
再生中にトラックバーを更新する関数を作成します。
private void updateTrackBar() { if (this.currentStatus == MediaStatus.Running && this.objMediaPosition != null) { this.trackBar1.Value = (int)objMediaPosition.CurrentPosition; } else { this.trackBar1.Minimum = 0; this.trackBar1.Maximum = 0; this.trackBar1.Value = 0; } }
上述したトラックバー更新関数をコールするコードを追加します。
まずは動画の再生が完了したときにトラックバーを0に戻すため、WndProc関数にコードを追加します。
protected override void WndProc(ref Message m) { : if (lEventCode == EC_COMPLETE) { : updateTrackBar(); } }
次に、1秒に1度トラックバーを更新するためにタイマーを設定し、そこからupdateTrackBar関数を呼び出します。
private void Form1_Load(object sender, EventArgs e) { : // トラックバーの更新 Timer trackbar_timer = new Timer(); trackbar_timer.Interval = 1000; trackbar_timer.Enabled = true; trackbar_timer.Start(); trackbar_timer.Tick += (sender, e) => { if (this.currentStatus == MediaStatus.Running) { this.updateTrackBar(); } };
続いて、マウスクリックとマウスの移動でシークバーを更新するようにします。
MouseDownとMouseMoveイベントハンドラを作成してください。
MouseDownについては、クリックされた場所とトラックバーの幅から比率を計算して、その場所に再生位置を設定するだけです。
private void trackBar1_MouseDown(object sender, MouseEventArgs e) { if (this.currentStatus == MediaStatus.Running && this.objMediaPosition != null) { if (e.Button == MouseButtons.Left) { double pos = ((double)e.X / this.trackBar1.Width) * (this.trackBar1.Maximum - this.trackBar1.Minimum); // トラックバー this.trackBar1.Value = (int)(pos); // 動画再生位置 this.objMediaPosition.CurrentPosition = pos; } } }
MouseMoveについては、基本的にMouseDownと同じですが、範囲外にマウスをドラッグされた場合の対応コードを追加したものとなります。
private void trackBar1_MouseMove(object sender, MouseEventArgs e) { if (this.currentStatus == MediaStatus.Running && this.objMediaPosition != null) { if (e.Button == MouseButtons.Left) { double pos = ((double)e.X / this.trackBar1.Width) * (this.trackBar1.Maximum - this.trackBar1.Minimum); try { if ((int)(pos) >= this.trackBar1.Minimum && (int)pos <= this.trackBar1.Maximum) { // トラックバー this.trackBar1.Value = (int)(pos); // 動画再生位置 this.objMediaPosition.CurrentPosition = pos; } } catch(ArgumentException) { // 位置を超えて設定してしまった場合は例外が飛ぶが無視する } catch(Exception ex) { MessageBox.Show(ex.Message, "error"); } } } }
C#でデスクトップのアイコン情報を取得したり、位置を変更したりする方法
これによりアイコン位置を記憶して復元するなどの操作をすることができます。
工夫次第ではアイコンの自動整理なんかもできそうです。
エラー処理をいれていないので適宜実装お願いします。
GUI構成
サンプルとしてフォームアプリケーションで、ボタン「button1」とリストボックス「listBox1」を配置します。
button1を押すことで取得したアイコンの情報をlistBox1に表示します。
なお、使うかどうかわからないのですがアイコン情報をすべて取得している箇所があります。
ここはご参考で(DEBUG:と書いている箇所)
デスクトップのアイコン情報の取得
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices;
enum WindowMessage { WM_KEYDOWN = 0x0100, } public const uint PROCESS_VM_OPERATION = 0x8; public const uint PROCESS_VM_READ = 0x10; public const uint PROCESS_VM_WRITE = 0x20; public const uint MEM_RESERVE = 0x2000; public const uint MEM_COMMIT = 0x1000; public const uint PAGE_READWRITE = 0x4; public const int LVM_GETITEM = 0x1005; public const int LVM_GETITEMPOSITION = 0x1010; public const int LVM_SETITEMPOSITION = 0x100F; public const uint MEM_RELEASE = 0x8000; public const uint LVM_FIRST = 0x1000; public const uint LVM_GETITEMCOUNT = LVM_FIRST + 4; public const uint LVM_GETITEMW = LVM_FIRST + 75; public const int LVIF_TEXT = 0x0001; [DllImport("user32.dll")] public static extern IntPtr FindWindow(string strclassName, string strWindowName); [DllImport("user32", EntryPoint = "FindWindowEx")] public static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2); [DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, uint wMsg, int wParam, int lParam); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead); [DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead); [DllImport("kernel32.dll")] public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType); [DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr hObject); // アイコンアイテムの情報を所持する構造体 // 構造体の情報は→を参照 https://docs.microsoft.com/ja-jp/windows/win32/api/commctrl/ns-commctrl-lvitema public struct LVITEM { public int mask; public int iItem; public int iSubItem; public int state; public int stateMask; public IntPtr pszText; public int cchTextMax; public int iImage; public IntPtr lParam; public int iIndent; public int iGroupId; public int cColumns; public IntPtr puColumns; public IntPtr piColFmt; public int iGroup; } private void button1_Click(object sender, EventArgs e) { GetIconPosition(); } public static int MakeLParam(int wLow, int wHigh) { return (((short)wHigh << 16) | (wLow & 0xffff)); } private void GetIconPosition() { // デスクトップのウィンドウハンドルを取得する IntPtr hWndDesktop; hWndDesktop = FindWindow("Progman", "Program Manager"); hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SHELLDLL_DefView", null); hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SysListView32", null); if (hWndDesktop == IntPtr.Zero) { // 壁紙を変更した場合等Program Manager→SHELLDLL_DefView→SysListView32ではなく // WorkerW→SHELLDLL_DefView→SysListView32になることがあるので、両方試す。 // WorkerWは複数あるのでループして目的の物が見つかるまで探す。 IntPtr hWorkerW = IntPtr.Zero; IntPtr hShellViewWin = IntPtr.Zero; do { hWorkerW = FindWindowEx(IntPtr.Zero, hWorkerW, "WorkerW", null); hShellViewWin = FindWindowEx(hWorkerW, IntPtr.Zero, "SHELLDLL_DefView", null); } while (hShellViewWin == IntPtr.Zero && hWorkerW != IntPtr.Zero); hWndDesktop = FindWindowEx(hShellViewWin, IntPtr.Zero, "SysListView32", null); } if (hWndDesktop == IntPtr.Zero) { MessageBox.Show("Desktop hwnd could not be retrieved.", "Error"); return; } // アイコンの数を取得 int iconCount = SendMessage(hWndDesktop, LVM_GETITEMCOUNT, 0, 0); // デスクトップ(explorer.exe)のプロセスIDを取得する uint dwProcessId; GetWindowThreadProcessId(hWndDesktop, out dwProcessId); // 取得したプロセスIDをオープンする IntPtr hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessId); if (hProcess == null) { MessageBox.Show("Desktop process could not be retrieved.", "Error"); return; } // hProcessに関連するメモリーを確保する IntPtr pProcInfo = VirtualAllocEx(hProcess, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); for (int i = 0; i < iconCount; i++) { byte[] iconNameBytes = new byte[256]; LVITEM[] vItem = new LVITEM[1]; vItem[0].mask = LVIF_TEXT; vItem[0].iItem = i; vItem[0].iSubItem = 0; vItem[0].cchTextMax = iconNameBytes.Length; vItem[0].pszText = (IntPtr)((int)pProcInfo + Marshal.SizeOf(typeof(LVITEM))); // LVITEMの後ろの領域を指す領域とする uint vNumberOfBytesRead = 0; // vItemに情報を書き込む // Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0)は配列vItemの0番目を意味する WriteProcessMemory(hProcess, pProcInfo, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead); // インデックスiのアイテムを取得する SendMessage(hWndDesktop, LVM_GETITEMW, i, pProcInfo.ToInt32()); ReadProcessMemory(hProcess, (IntPtr)((int)pProcInfo + Marshal.SizeOf(typeof(LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(iconNameBytes, 0), iconNameBytes.Length, ref vNumberOfBytesRead); // byte配列からアイコンの名前を取得する string vText = Encoding.Unicode.GetString(iconNameBytes, 0, (int)vNumberOfBytesRead); // \0以降にもデータがある可能性があるため最初の\0(=文字列の末尾)まで抜き出してそれをアイコン名とする int endOfTextIndex = vText.IndexOf('\0'); string IconName = vText.Substring(0, endOfTextIndex); // アイコン位置を取得する SendMessage(hWndDesktop, LVM_GETITEMPOSITION, i, pProcInfo.ToInt32()); Point[] vPoint = new Point[1]; ReadProcessMemory(hProcess, pProcInfo, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(typeof(Point)), ref vNumberOfBytesRead); string IconLocation = vPoint[0].ToString(); // DEBUG:アイテム情報をすべて取得してみる SendMessage(hWndDesktop, LVM_GETITEM, i, pProcInfo.ToInt32()); ReadProcessMemory(hProcess, pProcInfo, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead); // リストボックスに情報を追加する listBox1.Items.Add("location:" + IconLocation + " name:" + IconName + " iItem:" + vItem[0].iItem); } // hProcessに関連するメモリーを解放する VirtualFreeEx(hProcess, pProcInfo, 0, MEM_RELEASE); CloseHandle(hProcess); // 最後にアイコン描画が更新されないことがあるため SendMessage(hWndDesktop, (uint)WindowMessage.WM_KEYDOWN, VK_F5, 0); }
デスクトップのアイコンを移動させる
事前に[デスクトップのアイコン情報の取得]を参考にしてアイコン情報を取得しておいてください。
デスクトップのウィンドウハンドル(hWndDesktop)およびアイコンのインデックス(i)が必要になります。
ここでは例としてアイコン名がabcだったら座標(350, 50)へ移動させるものとします。
IconName = IconName.Replace("\0", ""); if (IconName.Equals("abc")) { SendMessage(hWndDesktop, LVM_SETITEMPOSITION, i, MakeLParam(350, 50)); }
懸案
アイコン名をキーに位置を記憶しておき、それをもとにアイコン位置を復元する方法を考え付くと思いますが、Windowsはショートカットであれば同名のファイルを作成できてしまいます。
そうなると復元するときに異なる2つのアイコンを同じ場所に移動させることになり、おかしな挙動をすることになります。まぁほとんどないと思うので同名のファイルを作らないでといった注意書きをする程度でいいと思います。
Windows版のGoogle Chromeからの通知を切る方法
Windows版のChromeを使っていて、Youtubeなどからライブ開始の通知がぽろろーんという音ともにポップアップされるのがうざったいときがありますよね。この記事ではWindowsの設定で、Chromeからの通知を切る方法をご紹介します。
通知オフの手順
1.Windowsスタートボタン→設定(歯車マーク)を選ぶ
2.[システム]を選ぶ
3.[通知とアクション]を選ぶ
4.[送信元ごとの通知の受信設定]からGoogle Chromeのスイッチを「オフ」に設定する
時間帯で通知をオフにする方法
1.Windowsスタートボタン→設定(歯車マーク)を選ぶ
2.[システム]を選ぶ
3.[集中モード]を選ぶ
4.時間帯等で通知を受け取るかどうかの条件を設定する
bluetoothデバイスが不明なデバイスとして認識されてしまった場合の対処方法
Windows10の大型アップデート等でこの現象になることがあるようです。
ドライバーがインストールされない(コード28)、OSに互換性のあるドライバーがないと言われ、デバイスが使用できない状態に。
以下を実施することで解決できました。
1.デバイスマネージャーを開く
2.不明なデバイスを右クリックしてドライバーの更新を選ぶ
3.「コンピューターを参照してドライバーを検索」を選ぶ
4.「コンピューター上の利用可能なドライバーの一覧から選択します」を選ぶ
5.「Broadcom」の「BCM2033 Bluetooth 2.4....」を選んで「次へ」
6. ドライバーに互換性がないうんぬん言われるかもしれないが無視してインストールする
5.で選択するドライバーはそれっぽいのを選んでいますが、ダメな場合はいくつか試してみてください。Bluetoothは本来OSに元から入っているドライバーで十分動作するはずなので、おそらくはこの対処方法で解決すると思います。
ちなみに自分が持っているbluetoothデバイスはUSB接続の↓です。
不明なデバイスは「BCM20702A0」という名前でした。
そのため上記5.でも頭にBCMが付いたドライバーを選択したのでした。
www.amazon.co.jp
突然Windows PCがお亡くなりなったときのレスキュー作業など
12年間使用していたマザーボードがお亡くなりになりました…。
突然のことだったのでディスクのバックアップはあまりとっていなかったのでここにレスキュー作業について書いていきたいと思います。適宜追記します。
ここでは新しいシステムドライブをCドライブ、レスキュー対象をDドライブとします。
Google Chromeのお気に入りの移行
1.まずChromeをインストールします。
2.以下のフォルダーをリネームします。
C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default ↓ C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default.old
3.以下の通りフォルダーをまるまるコピーします。
D:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default ↓ C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data\Default
CLIP STUDIO PAINTの設定の移行
1.まずCLIP STUDIO PAINTをインストールして、起動&ライセンス認証を完了させます。
2.CLIP STUDIO PAINTを終了します。
3.以下のフォルダーをリネームします。
C:\Users\Tatsuro\Documents\CELSYS ↓ C:\Users\Tatsuro\Documents\CELSYS.old
4.以下の通りフォルダーをまるまるコピーします。
D:\Users\Tatsuro\Documents\CELSYS ↓ C:\Users\Tatsuro\Documents\CELSYS
ただこれだけだと、クリスタ内のコンポーネントの位置などが復元できていないような…。
ドラゴンクエスト11(Steam)のセーブデータ移行
1.Steamでドラゴンクエスト11をインストールしておく
2.以下のフォルダーをリネームします。
C:\Users\taiyakisun\Documents\My Games\ドラゴンクエスト XI S ↓ C:\Users\taiyakisun\Documents\My Games\ドラゴンクエスト XI S.old
3.以下の通りフォルダーをまるまるコピーします。
D:\Users\Tatsuro\Documents\My Games\ドラゴンクエスト XI S ↓ C:\Users\Tatsuro\Documents\My Games\ドラゴンクエスト XI S
スタートアップに起動したいアプリケーションのショートカットを置く
C:\Users\taiyakisun\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup