統合版マインクラフト(PS4,Switch,PC,PE)で実績の解除方法 / 難易度HARD(バージョン1.17+)でのウィザー正攻法攻略記事もあり
個人的な備忘録です。
マイクラの実績は解除方法が添えられていますが、そこからだけでは解除方法がわからなかったものを記載していきます。適宜追加します。
実績名 | 解除方法 |
強靭なお腹 | ダッシュやジャンプを駆使して空腹ゲージを0にしたあと、腐肉を1つ以上食べる |
スナイパー対決 | 下記「スナイパー対決の画像」を参考に、だいたい家の前にいるラマの位置くらいにいるスケルトンスナイパーを弓で倒す。 |
安く買って高く売る | たまに沸く略奪者のリーダー(旗を持っている邪悪な村人)を倒し、村で襲撃イベントを発生させたあと、村人と交易をする |
友情の癒しの力 | ウーパールーパーが攻撃している相手を倒す |
海の藻屑 | 水中でゲーム内の一日(20分)を過ごす。水中呼吸のポーション必須。 |
漂流者 | ゲーム内3日間(60分)を乾燥昆布だけで過ごす。乾燥昆布を食べて放置すればよい。 |
丸石がいっぱい | 丸石30スタック分(1920個)を1つのチェストに入れる。ラージチェストにいれてもよい。 |
ヤギが浮くならなんでもあり | ヤギと一緒にボートに乗って、水に浮く。なぜか実績が解除されないことがあったが、何度かボートを乗り降りしたら実績が解除された |
はじまり?/はじまり。 | ウィザーを召喚する/ウィザーを倒す ※以下に正攻法での攻略記事あり |
スナイパー対決の画像
ヤギが浮くならなんでもありの画像
ウィザーの正攻法での倒し方(難易度HARD / 1.17.11現在)
ここでは、ウィザーを窒息させたりせず正攻法で倒す方法をご紹介します。
難易度はHARDで、マイクラのバージョンは1.17.11です。
1.17+では、洞窟の狭い場所で召喚してゴリ押す方法は通用しないように思えます。
青い頭の爆発によって天井が爆破され、すぐに上の方に逃げられてしまうためです。
そのため、戦いの場としてはできるだけ平坦な平原がよいと思いました。
装備は以下の通りです。
種別 | 装備 | エンチャント |
剣 | ダイヤモンド(ネザライト)の剣 | 聖なる力V(Java版ではアンデッド特攻V) |
弓 | 弓 | パワーV(Java版では射撃ダメージ増加V) |
頭 | ダイヤモンド(ネザライト)のヘルメット | 防護IV(Java版ではダメージ軽減IV) |
体 | ダイヤモンド(ネザライト)の胸当て | 防護IV(Java版ではダメージ軽減IV) |
脚 | ダイヤモンド(ネザライト)のレギンス | 防護IV(Java版ではダメージ軽減IV) |
足 | ダイヤモンド(ネザライト)のブーツ | 防護IV(Java版ではダメージ軽減IV) |
その他のアイテムとしては以下の通り。不死のトーテムが最も重要です。
・不死のトーテムを持てるだけ持つ
・力や再生などのポーションを用意する
・食料を用意する
・衰弱対策に牛乳も用意しておいても良いですが、牛乳はトーテムやポーション等の良い効果も消してしまうので、使いどころが難しいです。
戦いの前に
戦闘中にポーションを飲んでいるヒマがほとんどないため、戦いの前に飲んでおきます。
力のポーション(8分)や再生のポーション(2分)などを飲むとよいでしょう。
また戦いの最中にトーテムを再装備するため、トーテムの並びを見直しておくと良いです。
ぶっちゃけトーテムが戦いの要なので、ここが一番重要です。
ウィザーのHP満タン~半分まで
弓による攻撃を行います。
平原をウィザーを正面にとらえて横に避けるように、頭の遠距離攻撃を避けます。
とはいえ、避けるのが限界があるのである程度は当たってしまうことはしょうがないです。
ウィザーが黒い頭を3発、青い頭を1発撃ったあとは少し攻撃の手が休まるので、そのスキに弓を1発当てます。
これの繰り返しです。
HARDでの(?)衰弱状態は体力が満タンでもハート10個分すべて減らされてしまうため、不死のトーテムは必須です。
不死のトーテムが発動すると強力な体力回復効果が発動するため、ウィザーの攻撃や衰弱状態で死ににくくなります。
不死のトーテムが発動したら、すぐにインベントリを開いて次の不死のトーテムを装備します。
ウィザーのHP半分~撃破まで
ここからは弓が効かなくなるため、剣による攻撃を行います。
前半戦と同様に、ウィザーの遠距離攻撃は横に避けてかわします。
遠距離攻撃の手が休まる区間になったら、接近してできる限り剣で攻撃します。剣の攻撃が当たらない距離までウィザーが上昇したら、走って離れます。
ここでも不死のトーテムは必ず持つようにしましょう。発動したら即座に次のトーテムを装備します。
また、撃破直後、ウィザーは大爆発を起こしますので、ウィザーのHPが0になったら、すかさず遠くに離れましょう。
統合版マインクラフト(PS4,Switch,PC,PE)で実績を見る方法
少し迷ったので備忘録。
タイトル画面の右下にある「プロフィール」を選択します。
続いて「実績」を選択すると、実績一覧が表示されます。
ファイナルファンタジーXI(FF9) チョコグラフの場所スクリーンショット一覧
# | チョコグラフ名 | 発見場所 | スクリーンショット |
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.時間帯等で通知を受け取るかどうかの条件を設定する