はてなキーワード: KEYとは
(ようするに、アニメゲームマンガを見ながら政治運動に傾倒して、アニメゲームマンガを政治でぶっ叩くよりも、「ガチャを回すぞ、かわいい女の子を描くぞ、コスプレしたぞ」のほうがよっぽどオタクとしてきちんとした姿だってことに、最近まで気づかなかったって話です。)
背景は、同人作家。で、左派系思想にバックボーンを持ちいわゆるネットの論客とかもやってた。
いま、もう、俺たちの時代に通用したオタクしぐさはただの迷惑行為なのだということを感じる。
昔は、バンダナにジーンズをつけたオタクがいた。あれは当時の最新のファッションを後追いしたものだった。しかし、今見るとダサいしキモいし、痛々しい。
俺たちはネットで、「バンダナにジーンズをつけたオタク」をやっているのだということを自覚した。
ラブライブのスカートの線は現実女性に悪影響を与えるから許されない、という例の話は、はっきり言えば老害オタクしぐさなのだ。
もうすこし順を追って話そう。
俺たち30代40代オタクは、好む好まざるにかかわらず、政治にかかわることを必要とされた。(後から追記:考えてみればかかわる必要などなかったし、そう思うこと自体が、おかしいといわれればまさにそのとおりなのだが、なぜかそもそもかかわるものだと信じていた)
オタクというだけで、差別され、いじめられた時代を経験し、保守(左派系ラディフェミ政治家も含む)政治家がオタク文化を焼き払おうとした時代だ。
だから、オタクは政治にかかわって自分を守ることが要求された。
それゆえに俺たちのイケてるオタクしぐさ、というのは政治にかかわっていろいろ発信することだった。(後から追記:考えてみればなぜそう思ったのか心底わからない。オタクとして萌え萌え言っておけばよかったと心底思う)
サブカルとしての政治運動にかかわってるというだけで、一目置かれたし、あらゆるアニメを政治に結び付けて批評したりすることが最先端のオタクしぐさだった。
とりわけ人文科学、もっと言うなら大学で覚えたばかりの社会学や歴史学や心理学を利用してオタク文化を批評したり政治に牽強付会してサークルで議論したりネットに発表したりすることが最先端のしぐさだった。(後から追記:当時からすでにめちゃウザかったっぞというブコメもついている。すでにダサかったことに、その当時は全くおもわなかった。しかし実際はダサダサだったのかもしれない)
セーラームーンとフェミニズムのかかわり、エヴァンゲリオンの登場人物の心理解析、シスプリの大ヒット、涼宮ハルヒが社会に与えた変化と現象、発売されたばかりのアダルトゲームと国防体制とか、そんな愚にもつかない論考を出せば、転載サイトが記事を拡散し、バンバンブクマが付いて、はてなやFC2のブログが大いににぎわった時代を体験したのだ。
しかしその時代は、終わりを告げる。個人SNSの情報速度の加速に、この手の論考はついていけなくなった。より刹那的に、よりリアルタイムでの反応が求められた。
また、オタクの政治的立ち位置とかかわりも一気に変わった。まさか、よもや、自民党から表現規制反対の議員が出て、アニメゲームマンガを守る一本槍で戦い、全国比例で53万票も獲得するとは夢にも思わなかった。同時に、左派系議員にも表現規制賛成を叫び、多くのかつてのアニメゲームマンガ規制反対政党からも、アニメゲームマンガバッシングが飛び出すようになった。
こんな時代になってくると、もう、人文科学や政治にオタク趣味を絡めて、左派的価値観で作品を論評したり、オタクにかかわることが何の意義があるのか? ということになる。「この作品はリベラルなのかどうなのか」とか、「この絵はフェミニズムから考えると女性の抑圧ではないか」とか論評すること自体、もう「バンダナにジーンズのオタクがダサいのに自分はイケてると勘違いしている」ということになる。
いまどき、「艦これやアズールレーン趣味をやりながら正しい歴史認識を叫ぶ」というのも痛々しい。
そんな奴よりも、「ただネットに同人誌の一コマを乗せたほうがよっぽどRTといいねが来る」し「youtubeでレイヤーがSEKIROをプレイしてたほうが尊敬を集めるし面白い」って時代になった。
いちいち海外の友人と友達だなんてマウンティングをとる必要もなく、同人作家は海外絵師やファンと、レイヤーは海外レイヤーと相互フォローになってる。自分たちが海外に友人がいるんだぞとマウンティングの経費を大量に払ったのと比較にはならず、ナチュラルに異文化交流してやがる。
そんな老害になった俺たち世代がせめてもの抵抗として、注目を集める方法が、炎上とオタク文化批判だったことは悲劇である。要するに、「今のオタク表現は差別だ。許されない。俺が真の表現規制反対派として、表現を規制してやることがお前たちのためになるんだ」と言い出すことだ。
老害化を直視できないが、注目を集めて最先端に残るためには、世界を破壊しようとするしかないのだ。
でも全員がそんなことできるわけじゃない。
昔の時代を忘れられずに、しかし、今の時代に適応できない人間はかなりの数いる。
文化の中心にいない人間が、ついに最先端の若者たちを攻撃する時代になった。もう完全にやってることが石原慎太郎である。
事実、かつては左派系表現規制反対派の論客たちが、次々と規制派へと転向しフェミニズム系規制論を唱えるようになったのは偶然じゃない。
いま現在、左派系価値観で、オタク趣味を語ることの価値は暴落し、何の意義もない。唯一かろうじてオタク文化の真ん中に居座るには、規制派としての椅子しか残されていなかった。
さんざん世話になった左派思想である。どんなにくだらない、萌えオタ表現たたきであったとしてもこの際仕方がないという面は理解できる。
自分が老害化していることを認めず、「今のオタク文化を矯正してやるんだ」と息巻いては見たものの、周囲の人間からは「迷惑でうるさい老害が来てるよ、お前は石原慎太郎と同類だよ、劣化したな」と軽蔑のまなざしを向けられる政治語りオタクを何度も見てきた。
いま、政治とオタク文化を結びつけるには「差別」という強いカードを切って、「お前らは差別しているんだ。いや差別じゃない」とこじつけるしかない。
だがそれを繰り返せば繰り返すほど、余計にダサい老害になるというのに。
昔は20本以上見ていたのに。
ソシャゲの周回もおっくうだ。
そのくせ、ひどく怒りっぽくなってアニメとか新作を見るとくだらないと思える。
もう認めよう。
俺たちは石原慎太郎と同じ道を歩んでいる。
追記1 ブコメに「もう虐げられてるサブカルじゃなくて、超どメジャーカルチャーなんだよ。」ってまさにそれなんだよね。マイナーなサブカルロックバンドが好きだったのに、メジャーになったとたんに「堕落した。メジャーに媚びた」って、昔のファンがアンチになるでしょ。あの状態。今更、メジャーなサブカルとしての生き方をどうやってやったらいいのかわからないのだ。だけども、この流れは今更もう止められないだろうということも理解してる。
追記2 自分は30代だが、この世代がどうとかいうのはたしかに間違いだった。もっと上の世代にもそういう人が多いというのは理解してる。世代というよりは、政治にかかわってオタクを語ろうとするクラスタの話なのかもしれない。
追記3 その老害ムーブを、まずやめろというのは正しいし、自分はそうならないようにしているがそれでも、政治語りがダサいということを受け入れるのは難しい。
追記4 いろいろ反応を見て気づいた。なぜ政治オタク語りなんてやってたのか。全然わからないし必然性もなかった。本当になんでやってたんだろう。
追記5 「オタクじゃない、政治サブカルだ」というのは本当にそうだと思う。サブカルがオタクに文化的な敗北したから、サブカルから一段下にオタクを見下しつつかかわってた人たちの軸がすっ飛んだんだと思う。政治サブカルが破綻して、オタクだけが残ったんだと思う。
追記6 なぜ害だと気づけたかというと、政治サブカル系のアカウントが次々おかしくなっていったから。かつてはまともだったはずなのに、今はもう何なのかわからない人たちがたくさん生まれ始めた。それを何だろうと考えた結果。
追記7 KEYについては正直よくわからない。やってないから。ただ友人は、CLANNADをガンガン推してきたが、ぶっちゃけ観てない。絵柄がちょっと合わなかった。
追記8 「アニメから思想が消えた」とか、無理やり政治問題や世相を切る道具として使って政治敵を攻撃したり政党批判に持っていくのが、ダサい時代になったということだと思考。
追記9 30代は若い若い、と言われてる。確かにもっと年齢層が高い印象。しかし、この手の老害化は30代でもかなり目撃してる。
追記10 お前39だろ、39だろ、っていうやつら。39歳だってまだ30代の仲間だろ! いじめよくない! どうしてそう、必死に30代にしがみつかせてくれないんだ。
追記11 これを規制派とか反規制派とかいうくくりで読むこともできるんだろうけれど、害だなあと思うようになったのは、「本気でオタク表現に対してマジギレ」したり、「本気でオタクはネトウヨだが俺たちは違うんだ」と立ち振る舞う人が、オタク系政治に浸透してきて「本気かよ」とドン引きしたのが最近の率直な印象。「オタクは腐敗してる」とかいっても、どうせごっこ遊びだろ? いつもの極論ワロスw って受け止めてたが、ここ最近、本気で怒って、本気でつぶそうとしてる人が自分の周囲でもマジに出てきた。昔は評論遊びをしてる部分はあったと思ったけれど、実際には他者に多大な迷惑をかけまくってたんじゃないかと考えるようになった次第。
追記12 ラブライブのスカートの線で、マンガ家が「そんなの大した問題じゃないだろ。俺の健全な絵でも見ろよ」とオタクを軽く挑発するオタク老害しぐさをやって「本気の攻撃をされたと認識したオタクがフルボッコにした」ことがあるけれど、あれを見るに、もう今と昔ではオタクの自意識も作法も違うと思う。昔から嫌がっていた人が可視化されただけかもしれないが。
https://b.hatena.ne.jp/entry/s/togetter.com/li/1456047
ハッカーの件が疑わしいみたいな話だけど、20年前くらいには多少あれな人たちの間では、それこそ今の出し子のようなもんで、おろしてくれる人探してるって話はしばしば聞いてた。
20年前って本当にバカみたいな時代で、例えば某ATMは、50万円おろしても1万円残して49万円とるとするじゃん。そうすると機械は出金されなかったということで、一円もおろしたことになってないの。ATMの中が空になるまで出せるの。バカだよね。
実際wifiだって出始めのころはみんなkeyつけずに設定してるから、新宿なんて今よりフリーwifiだったし。
実際闇金なんて聞かなくなって久しいしな。
推し、めちゃくちゃ好きで超会いたくて会いたくて気づいたら五年くらい経っていたんですが、ついに今年推しの名前が事務所から消えてテニパにもメッセージ無くてテニミュも全国立海後編始まったしこれ以上ないタイミングなのでさよならブログを書こうと思って書いています。
かなりとっ散らかった文章ですが、読んで頂ければ幸いです。
大好きなので、大好きなのは辞めないと思うんですが、思い出にして前に進みたいのでさよならします。
私が岡崎和寛くんを知ったのは高校三年くらいの時でした。当時、テニミュを好きな友達がいて、テニプリ原作が好きだった私はものの見事に引き摺り込まれました。
高校三年生は受験で遠征もできず(地方の貧乏学生だったこともあり)、短大の一年生になって初めてテニミュに行きました。最初に行ったのは公演ではなくて大運動会2014だったけれど。
そこで初めてテニミュを浴びて、目の前で動く推しを見て、岡崎和寛くんが好きなフォロワーとも会いました。幸せだったな〜〜楽しかった!障害物競走でビリになってみんなに見守られながらゴールする岡崎和寛くんの深司めちゃくちゃ可愛かった。本当に可愛かった。夜公演の前にブロマイドが売れ残っててフォロワーと落ち込んだのはいい思い出(よくないけど)(公演後は売り切れてた)
運動会に神尾が欠席で、公演の後に神尾のスペースを空けて不動峰で写真撮っててすごいほっこりしたなぁ。
その後、セカンド全国立海が始まって、岡崎和寛くんが好きなフォロワーや友達と観に行きました。実はその全国立海の公演期間中に私を岡崎和寛くんに肯定される出来事が起きてしまいました。確実に身バレするから書けないけど。
私は親やクラスメイトにずっとずっとそれを否定され続けていて、それをすること自体はすごく好きなんだけど、時々ものすごく嫌気が差すことがありました。しかもその出来事の直前に、ショックな事があったので余計にきつい時でした。
うーん、ぼかして書こうとしているので訳の分からない文章になっていて申し訳ないです。でも、とにかく自信がなかったとだけ分かっていただければ大丈夫です。
そんな時に推しに"それ"を肯定されてしまったんですよね。今考えればそりゃやばいですよ。ずっと否定され続けていたことを推しに肯定されたんだから。
それからはなんかもうすごくて、超しんどかったけど何とか立ち直ってそれを続けられて、今でも続けられています。こんな幸せなことあるか〜〜?!ない!
そのきっかけで不動峰のオタクのフォロワーができたし(それまで岡崎和寛くんが好きなフォロワーとリアルの友達くらいだった)なんなら今でも超仲良いフォロワーがいます。
高校の個人ホムペを見ていた頃、好きだった方と繋がれたりとかもありました。いや〜〜すごいな?!
岡崎和寛くんのおかげで、好きなことを続けようと思えて、狭いインターネットの世界がすこし広がって友達ができました。
全国立海の公演期間中、ほんとうにほんとうに幸せハッピークソ野郎でした。
所詮行く公演も少ない在宅オタクだったのですが、日替わりレポをチェックしたり、かずくんとゆうきくんの差し入れ合戦を見てニコニコしたり、体調を崩してるらしいかずくんを心配したり、バルズのお揃いのキャップに湧いたり、全部新鮮だったので在宅でも楽しかった。
俳優オタク一年生だった私は何もわかっていなかったので、金を出すべきとか、公演沢山入るべきとか思いつきもしませんでした。周りにもそういう人がいる訳でもなかったし。本当に何も知らなかったしわかっていなかった。
今思えば沢山公演入っとけって思うけど。結局こうなってしまったんだから。
いやでもかずくんの日替わり天才だったよな〜〜〜〜本当に大好きなんだよなぁ。日替わりで日吉や裕太と仲良くなっていく過程をやって最後には友達になれたりとか。『深司信じられない』もかずくんはゲームが元ネタって知らなくて、偶然思いついて使ったらファンレターでゲームのネタだと知った、みたいなのとか。日替わり毎日考えなきゃいけないのに、全国立海終わった後は楽しかったです!の一言で終わらせてるんだもんな。
やっぱ天才だよなぁ
全国立海の大千秋楽をライビュで観て、最後の日替わりで泣いて(本当にあれはずるいけど天才だと思った)、映画祭があって(ドラキュラのかずくん会いたかったな〜〜行けばよかったな………)、ドリライがありました。
ドリライ、ライバルズの出番が鎬だけで謀反……って気持ちだったな。ソロ聴きたかったな。でもはじめてのドリライ楽しかった。
ドリライでは初めて岡崎和寛くんとハイタッチして驚きすぎて腰抜かした。いやだってまさかできると思ってなかったし俳優オタク一年生だったし。同行者の方にちょっと心配された(それはそう)
大好きだなぁ。
でもまさかドリライ2014が最後に岡崎和寛くんに会える機会だと思わなかったなぁ。
いや普通思わないよな?それで終わりだなんて。
確かにドリライの後に仕事決まってなくて不安だった気はするけど、元々仕事が多い人ではなかったし(書いてて悲しくなってきた…)そのうち決まるだろうと思ってたな。能天気だなその時の私。決まらないから安心しな。
ドリライが終わって、かずくんの仕事が決まらなくて不安で、サードのキャストが発表されて、そのなかに健人とまちゃがいて二人とも全国立海のアンダーやってて、サードのお披露目が近づいてて、かずくんの誕生日が近づいていった。
かずくんの誕生日にアメスタの配信が決まって、喜んで見た。すごい酔っ払ってたな笑 でも楽しそうでかわいかったな。
多分アメスタの次の日か前の日のどっちかだったんだけど、サードのお披露目にかずくんが行って、サード不動峰のキャストに囲まれててああもう先輩なんだなって思った。
健人とツーショット撮ってて嬉しかったけど複雑だった。多分まだいまいち健人を受け入れられてなかった。
それからはサード不動峰公演が始まって、チムライがあって、やっと健人の深司が受け入れられて、ルドルフ公演があって、ドリライがあって、サード不動峰が一旦テニミュから離れた。
かずくんはたまにツイッター更新して、その度に私はひっくり返るような気持ちになったりフォロワーからリプ飛んできたり、インスタ始めたり、インスタのお陰で数年ぶりに動いてるかずくんを見れたりした。
Love's by keyのパーカー買ったりもしたなぁ。まだ家にある。捨てられない。
なんか五年ってすごく長い時間のはずなのに、アメスタからかずくんのことで何があったかが数行で終わってしまうの、とても悲しい。数行ぶんくらいしか私は知らない。
当然といえば当然だ。その時から岡崎和寛くんは俳優の仕事をしないつもりでいたのだろう。むしろ気まぐれでツイッターを更新したり、インスタを更新していたことが奇跡だったのかもしれない。
インスタのタグ付け?で岡崎和寛くんが何か他の仕事してるんだろうなっていうのを知ったもんな。
岡崎和寛くんが今何の仕事をしているのか、結婚しているのか、してないのか、なにもわかんないけど、わかんなくていいけど、幸せに暮らしていてくれればいいなと思います。
話がすっ飛びますが、12月19日からサード全国立海後編が始まりました。ライバルズ、つまり健人の深司くんが出ています。
健人にとってはセカンドでアンダーで出ていた公演にようやく出るってことなんだなと思うと本当にエモすぎて死んでしまう。
ここまで長いようで早かったなぁ。いや長いか。
私の取れたチケットは12月23日の公演でした。あれだけの倍率で取れたチケットがこの日ってもうめちゃくちゃ笑ってしまった。だってこの日岡崎和寛くんの誕生日だよ、私早くこの日をなんでもない日にしたかったよと思った。軽い気持ちで申し込み出すもんじゃないなと学んだ日でもありました。(あとでにちかちゃんの誕生日だってことも知った。おめでとう)
今年もまた12月23日が特別な日になりました。きちんと岡崎和寛くんの誕生日ケーキも食べました。テニミュを観ました。凄かった。
もうね、私絶対これ岡崎和寛くんに観て欲しい。絶対絶対観てほしい。健人の中に岡崎和寛くんが生きているよ。本当だよ。でもそれを伝える手段が無いに等しいんだから笑っちゃうよなぁ。
次から少しネタバレなのでまだ全国立海後編を観ていない方は数行飛ばしてください。
まさかスポットをねらえが聴けるなんて思ってなかった。メドレーがファーストのままだからだろうけど。
あとやっぱり一番は日替わり………かずくんがセカンド全国立海で日替わりやってたシーンと同じシーンで健人も日替わりやると思わないじゃん。ビックリしすぎてひっくり返るかと思った。そんなのエモすぎて死ねるじゃん。それにまさかGMKKもやるなんて思ってなかったし。
健人が。セカンドでアンダーで出てた健人がサードの全国立海でGMKKやってるの、マジでマジでエモい以外の言葉でどうやって表せばいいんだ。こんなことってあるか。
とどめはGMKKのコールだった。深司だった。
都合のいい深読みしすぎなオタクだから、岡崎和寛くんが誕生日だから深司がコールだったんだなと思ってしまった。
本当にこんなの死んでしまう。
チケットはその日の公演一枚しかなくて、まあ実際観たらもっと観たくなるだろうなと思ってたけど、とんでもなく満足してしまったので今のところその欲があんまりない(いや、チケットがあれば行きたいけど………)
あと、色々見てて気付いたことがあるんだけど、健人のなかに岡崎和寛くんが生きている。どうとか具体的にはあまり書きたくない…………けど確実にそうだと思う。
健人にかずくんの深司がどう写ってたのかずっとわからなくて、正直かなり不安だったけれど、健人のなかに岡崎和寛くんが生きてることが分かってすごく嬉しかった。本当にうれしい。
よかったな〜〜本当に良かった。
さよならします!思い出にします!って言ってここまで書いた癖に会いたくて仕方ないな。かずくん、本当にキモくてごめんなさい。
私はずっとずっと岡崎和寛くんに直接会って、私を肯定してくれたことにお礼を言いたくて5年も引きずっていました。もうここまできたら呪いだよ。どうしてこの程度のことぐらいが叶わないんだろう。不思議だなあ。
つくづくオタクと推しを繋げているものって脆いなものなんだなと思う。推しが行方をくらましたらもうオタクは推しが何をしているのか、生きているのかすらわからないままなんだよ。
改めて考えるとめちゃくちゃしんどいな。当然のことだけれど。
推しにはオタクのことなんて気にせずに生きていてほしいと思う反面、推しのことが知りたくて仕方ない生き物だから仕方ないのかな。矛盾しかなくて本当に面白い。
岡崎和寛くんがサード全国立海後編に行ってくれたらもう思い残すことがないので、安心して死ねるなぁ。人生短いけどできるだけ思い残すこと無い方がいいじゃないですか。自分ではどうにもできないけど。
どうにか行ってくれないかな〜〜そしてそれを教えてくれたらいいな………
だらだらと色々書いてみて、とんでもなく短い間だったけど私は岡崎和寛くんにいろんなものを貰ったんだなと思いました。
テニミュがめちゃくちゃ楽しいと思えたこと、付き合いが長くなるフォロワーと知り合えたこと、自己肯定感、幸せな思い出、沢山沢山貰いました。岡崎和寛くんがいなければここまで沢山幸せなことがあったかどうかわかりません。本当にあの時は幸せでした。岡崎和寛くんにはどんなに感謝してもしきれません。
岡崎和寛くん、本当にありがとう。あなたがいなければ私は今どうやって生きていたのかあまり想像ができません。多分今よりもっと死にたかったと思う。
直接会ってお礼を言うことはもう叶わないので、届きもしそうにないところからお礼を言わせてください。
初めて増田になりました。
学生の頃にCLANNADのアニメを観て、それは大層泣きました。
シナリオの都合のよさとか、主人公にキツい運命を与えすぎでは?とか、そういう理屈を超越したところにこの作品はあって、京アニは見事にこの物語を演出してみせたと思う。
あの頃は家族とか友達とか人のつながりっていいな、と大まかにはそんな感想だったと思う。
しかし今の私は違う。見終わって、人はなぜこんなにも傷つきながら前を向いて生きなくてはならないのだろうと思った。
いやまあそもそも、5年目にして転職を2回しているような人生なので察してほしい。
働き続けることがこんなにもつらいのだと、布団の中で思う日々だ。
多分この日記を開いてくれた人はCLANNADやリトバスをすでに履修済みだろう。よって割愛する。
私の胸を打ったのは、AFTER STORYに入って、朋也が働き始めたところだ。
卒業後にプーだったことを負い目に感じていた主人公は、自分で仕事をみつけ、住む場所をみつけ、愛する人の5年目の高校生活を支える。
その18歳の岡崎朋也がなんともいじらしく、可愛く、行動してみせた自分がどこか誇らしく瞳が輝くも、あっという間に現実を突きつけられてしまうのだ。
新居に渚を迎えて浮ついた気持ち、職場の先輩の芳野と初めて車で現場に向かったときに、すれ違った家族を窓越しに見送った時の未来を期待する表情。
それがもうたった一日の労働で、家に帰ったら愛する渚の話に耳を傾けられないほど疲れ切ってしまうのだ。
学生時代にはその細やかな描写に気が付かなかった、まったく印象に残っていない。
改めて視聴した今回は、汐をめぐる物語以上に、朋也が働き続ける姿が目に焼き付いて離れないのだ。
本人も作中で話してはいるが、学校生活では友人たちの悩みを解決し、手を差し伸べてよい方向へ導いてきた朋也が、
人を導くことができるという自惚れが、働き始めたことで一瞬で瓦解する。
労働とは、そりゃ楽しいこともあるかもしれないけれど、大多数は生きるために嫌々行っているものだ、
学校が楽しくないからと不良のような生活を送っていたあの朋也が、逃げ出さずに仕事と向き合う姿は、まさしく日本という社会で生きるためには組織に所属して労働しなくてはならないという現実を突きつけてくる。
古河家だって、流行っているパン屋ではないことから、渚や朋也の目にみえないところで重いそろばんをはじいているのだろう。
朋也は渚を失ってからも仕事をしつづけた。本人はそれを汐からの逃避だといったが、生きるためにはお金が必要で、庶民は働かないと生きていけない。
どれほど傷ついても生きることから逃れられないのなら、仕事をしたり、人とかかわって生きていかないといけない。
汐の治療のために仕事をやめた朋也は、汐が亡くなってしまったら、もう死のうと心のどこかで覚悟していたのだろう。(原作で描写あったっけ…)
だから生き続けるための仕事をやめて、それを察した芳野は戻ってくるようにと声をかけた。
5年目に触れたCLANNADは家族っていいなとか楽しい友達が欲しいな、とかCLANNADは人生とかそういうことも感じたけれど。
傷ついた人間もその傷が癒えずとも前を向いて生きろと、そんな空をつかむような悲しいエールを受け取ったのだ。
思いっきり割愛するが、リトバスの主人公は親友たちを一度に失うという大きな傷を負う。
そして彼らが死ぬ運命は避けられぬのだと、その痛みを抱えてまでも生きろと言われる。
物語を通してハートが強くなった理樹は喪失をも受け止めて強く生きようとする。
まあ最終的にはうまいこと物語が展開してハッピーエンドになるのだけれども。
だーまえは何かとプレイヤーたちに強く生きてほしいと願っている気がする。
書を捨て街に出よう、じゃないけれど傷ついても現実逃避せずに真っすぐ生きてね、という応援。
ビジュアルアーツ20周年のイベントで配布された曲なのだが、わざわざイベントに来たような熱心なファンに「僕はもう大丈夫だから 今度はそう、きみが幸せになる番だよ」なんて語りかけてくる。
オタクなんて大小あれども、傷ついて生きてきて、エンタメにそれを救われているような人間ばかりなのだ。
そんなオタクたちに、現実に立ち向かえとスパルタ的に奮い立たせようとする。
あと多くのkey作品は現実から逃げるとBADED行きなのだ、智代ルートなど非常に印象に残っている。
そこまでして、どうして生きていかねばならないのか、、、なんて思う。
俺たちは人生の主人公なのだから、現実から逃げずに、居心地のいい環境を作って、ささやかながら生きがいをみつけて、VAにお布施して生きろと。
才能もない、とりえもない、頭もよくない、覚えも悪い。
ぐずぐずに崩れた自尊心を取り戻す手助けをしてくれる渚や朋也、恭介や理樹、そんな存在は周囲にはいない。
久々にCLANNADを観て、そりゃあもう想像外の感想を抱いたのだ。
現実をまっとうに生きている人々が圧倒的に多い世にこんないじけた文章を残せるのなんてここしかない。
自室に引きこもっていたようにみえた恭介だって、実は虚構世界で四苦八苦していた。己の失敗に落胆してはいても、決して行動をやめていたわけではない。
生きることとは行動なのだと、布団の中でスマホを触るオタクへ作品を通して鼓舞している。
もしもここまで読んでくれた人がいたらありがとう。
サマポケ面白かったから買ってプレイしてね、プレイし終わってたらFD発売か京アニでアニメ化することを一緒に願おうね。
あとVAにできることは、だーまえの後継者を必死に探して育成することか、keyを畳んで新たな才能で作品を作るか、だーまえの治療費を全額出してあげてkeyブランドを守るかだ。
オタクの人ら、70年代から内でも外でもひたすら喧嘩してる連中のあつまりなんですが…。
宮崎駿や高畑勲が組合作って労働争議やったり、庵野秀明らがアマチュアから商業業界に無理くり入り込んだり
ポルノ分野で力をつけてメジャーに乗り込んだり(Keyとかニトロ)、タフな人はたくさんいるんですよね。
もちろん弱い人もいるでしょうが、それはどのような属性の人にもいるかと思われます。
社畜が会社を訴える物語は、経済小説という分野になるのでファンタジー路線のライトノベルには向いてないという話ですよね。
オタクが逃げている、というのは全くそぐわない。やろうと思えばできるけど、市場に対して有効かどうかという問題です。
ほい。なんとなく波長に合わなかった面々も多いのであまり気にしないで欲しい
ただ、"死ねばいいのに"といった非生産的なタグを使ってるidは積極的に非表示にしてる
最近ようやくブコメに生産的なコメントばかり並ぶようになったけどブクマ数2桁くらいの新規idが日々増殖しててなかなか大変
b:id:abcdefghijklmnopqrstuvwxy5
b:id:kimokute-kanenonai-obasan
b:id:sushisashimisushisashimi
ざっくりだし同じこと言ってるところもあるかもしれないけど、自分の解釈はこんな感じ。
・2000年以前は社員数名の弱小エロゲメーカーが小粒の良ゲーを発売できていたが、ボリュームの重厚長大化によって開発期間が長期化、開発費は高騰化し、弱小エロゲメーカーの体力がもたなくなった
・上記に関連して、そもそも小粒のエロゲーなら流通に乗せる必要もなく同人で出せばいいということに気づいた
・2000年移行のファイル共有ソフトのカジュアル化も弱小エロゲメーカーの沈没を加速した
・PS2/PSP(Vita)の頃に全年齢対象版を出す流れがあって割と売れたので、そもそもエロゲである必要があるのか?と気づいた(Key)
http://kazenotori.hatenablog.com/entry/2019/04/14/113600
00年前後が青春ど真ん中だったエロゲヲタのひとりとして衰退理由を一言でまとめると、、、
だと思う。
Leafでいえば『雫』『痕』『To Heart』。Tactics/keyでいえば『MOON.』『ONE』『Kanon』『AIR』『CLANNAD』。TYPE-MOONは『月姫』『Fate/stay night』。エロゲではないけど同人の流れをくんだ『ひぐらしのなく頃に』。
この辺のソフトはプレイヤーを熱くさせ、語りたい欲を大いに刺激し(葉鍵板なんてのもあった)、「これエロゲーじゃないから泣きゲーだから」などという妄言を口走りながら周囲にプレイを勧めさせるだけの力があった(売上だけなら『鬼作』とか『大悪司』も当時強かったけど語るもんでも勧めるもんでもないから伝播力に欠けた)。
これらはざっくり「伝奇/サスペンス」「泣き」に分けることができてそれぞれブームを作ったけど、かなしいかなそれに続くブームはつくれなかったし、フォロワー作品は年を追うごとに小粒化して(初期は『sense off』とか『みずいろ』とか『秋桜の空に』とか『それ散る』とか良質なフォロワー作品がいっぱいあった)エロゲ全体のブームを急速に沈下させた。エロゲの時代は突然やってきてあっというまに終わった。
自滅、というのは言い過ぎかもしれないが、文化として根付かせることができなかった、ぐらいは言ってもいいだろう。
粒が小さくなって新しい体験が提供できなくなったエロゲは世代交代(『恋姫シリーズ』世代はいると思ってる)に失敗したし、熱狂してた連中はエロゲといっしょにオタクを卒業するか新たな最前線へと旅立っていった。
それは『ラグナロクオンライン』/『東方』(ROは2002年開始だけどコミケの流行が葉鍵/型月→RO→東方と変わっていった(型月はしぶとく東方と共存してたような記憶)のは大きなトピック)だったり、ラノベ(西尾維新/『ハルヒ』/『とある』/『ゼロ魔』)だったり、ニコ動/ボカロ+アイマス文化だったりした。
ブームが完全に去った現代はソシャゲ(『艦これ』/『デレマス』/『グラブル』/『FGO』)でゲーム体験を満たしつつエロはその同人で摂取する時代だから本格的にエロゲの出番はないだろう。ニッチな需要は同人エロゲが担っているから尚更だ(『奴隷との生活』はヒットしたなあ)。
1. ラノベ・深夜アニメ・ソシャゲ(あるいはスマホゲー)など他のメディアに客を奪われた。
2. ファイル共有ソフトなどにより海賊版が蔓延して購入者が減った。
3. CDからDVDへの移行、スマホの普及、光学ドライブのつかないノートパソコンの普及など、周辺環境の変化によりプレイヤーが減った。
の4つがかかげられていたけど、
2. は共有ソフト以前にコピー問題があったので要因とまではいえない
3. はスマホの普及以外論外(エロゲをやるためにパソコンを買う・組む連中は多数いた。DVDへの移行なんて屁でもないし、光学ドライブがつかない云々はDL販売とかUSBドライブの存在を無視してる)
4. は正しい。制作コストの増加とプレイコストの上昇は別問題なので切り分ける必要はあるが、これらの問題は大きかった
という所感。
上記以外の理由としてはこのエントリの主張である「オタク系サブカルの最前線という地位を失ったから」と、もうひとつあるとすればスマホの登場による可処分時間の細切れ化。エロゲをやるようなオタクはもともとインターネットとの親和性が高かったわけで、スマホの登場でネットに常時接続する消費スタイルへ移行すると、パソコンに向かってじっくりエロゲをプレイするなんてことが難しくなった面はあると思う(ここに物語の長大化によってプレイコストが上昇した問題がからんでくる)。
まあ同人エロゲもエロゲといえばエロゲだし、DMM GAMESのエロゲも形をかえたエロゲと言えるだろうし(大本のオモコロの記事はまさにその宣伝だ)、FGOもエロゲに含めれば(含めるな)過去最大のエロゲ市場が爆誕してると言えるのかもしれないが。
Q. 「オタク系サブカルの最前線という地位を失ったから」ってそれトートロジーじゃないの?
A. そう見えるかもしらんけど、オタクを熱狂させる弾がなくなったから、という話をしてるつもり。
逆になんで00年前後にそういう作品が雨後の筍のごとくでてきたかというとまあ割と謎なんだけどひとつ言えるとしたら若いクリエイターに申し訳程度のエロさえつけてれば自分のやりたいことをやれる場所だって認知されたことがデカいんじゃないかなーって(日活ロマンポルノみたいなやつって言えば伝わるのかね)。
『Phantom -PHANTOM OF INFERNO-』ってエロゲがある。ニトロプラス(今はたぶん刀剣乱舞で有名)の処女作でシナリオはぶっさん(虚淵玄。今だと『まどマギ』で有名……ってそれももう古いか)。
アメリカに旅行した青年が殺しの現場を見たせいでマフィアに拉致られ暗殺者をやらされるって話なんだけど、ハードボイルド小説か映画かってあらすじでもうエロゲじゃないよね。で、なんとこのゲーム暗殺に使う銃を選べて、なおかつその銃がポリゴンで表現されてた上に、どの銃を選んでもシナリオには一ミリも影響がない、というのが爆笑ポイントで単に作り手がそういうの好きなだけっていう。当時すでにIllusionとかがポリゴンエロゲを世に送り出してたとはいえ銃だけポリゴン表現にしたエロゲって『Phantom』が最初で最後じゃねーかな(ゲームはめっちゃ面白かったよ念の為)。
『雫』だって『新興宗教オモイデ教』のフォロワーだし、菌糸類が菊地秀行とかの影響モロに受けてるの見ても、外の文化にエロをつけてエロゲの流通に乗せる、は所謂たまによくあるってやつだった(そういうのの元祖はたぶん蛭田昌人と剣乃ひろゆき)。
まあ結局売り手も買い手もスケベ心があったんだよな。当時はエロさえ入れてれば一定の購買が見込める市場で、市場が未熟な分、制作コストが安くすんだ。買う方としてもエロがあるだけでオトクな感じがしたし地雷でも許せた(Tony絵に騙されて買った『Partner』ですら俺は許したよ)。上で挙げた諸作が仮に非エロだったらここまで売れてなかったと思うね(『CLANNAD』とか『ひぐらし』は地盤を築いた後だったからヒットした説)。
エロゲ(商業パッケージ)の売上は2015年に底を打っててV字回復しているとか,10年代でも名作はあるとか,本当に崩壊したのはエロゲ批評のコミュニティだとかいう話をすればいいんです? / “エロゲが衰退したのはラノベのせい、、、ではない”
https://twitter.com/nix_in_desertis/status/1117750519840198656
なんだろな,一連の流れを読んでいて思うのは,『千桃』とか『サクラノ詩』とか『金色ラブリッチェ』とは言わんにせよ,『ホワルバ2』とか『はるくる』とか『つり乙』あたりをスルーされると,お前エロゲ追わなくなって10年近くないか感強くて,一気にもにょるんだよな。
https://twitter.com/nix_in_desertis/status/1117753560047898624
こういう論旨を理解せずに訳知り顔するやつが一番むかつくんだよね。
とりあえずエロゲ市場規模は02年の段階で560億(財界さっぽろ)、15年の実績値で150億(矢野総研)。V字回復というからには18年実績値で300億ぐらいに戻してるんだろうな?
そして本稿は00年台前半にエロゲ市場が盛り上がったあと衰退した理由をその当時オタクシーンの最前線をはれる弾がありその後そういうのがなくなったから、に求めてるのであって、それ以降にエロゲとして名作と呼ばれる作品があったかなかったかなんて話は一切していない。
俺が最後にやったエロゲは『もっと!孕ませ!炎のおっぱい異世界エロ魔法学園』(2018年4月27日発売)だ。ゲスパーすんなヴォケ。
またムカつくコメントがついたら全力で殴りに行く。
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // int blocks[100][100]; BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); x = 0; y = 0; boxType = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); for(int x = 0 ; x < 100 ; x++) { for (int y = 0; y < 100; y++) { blocks[y][x] = 0; } } if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int x; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48*9,48 * 100 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } int boxType; BOOL WriteBoxOLDBox() { int width = 24; HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 48)); for (int y = 0; y < 30; y++) { for (int x = 0; x < 8; x++) { if (blocks[y][x] == 0) { continue; } RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); } } DeleteObject(hBrush); return FALSE; } BOOL WriteBox() { WriteBoxOLDBox(); switch (boxType) { case 0: return WriteBoxI(); case 1: return WriteBoxL(); case 2: return WriteBoxZ(); } return TRUE; } BOOL WriteBoxZ() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxL() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 246 , 48)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) -1 ; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) -1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxI() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB( 246 , 48 , 48)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); //Rect.left += width; //Rect.right += width; Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL SaveBoxI() { blocks[y ][x] = 1; blocks[y+1][x] = 1; blocks[y+2][x] = 1; blocks[y+3][x] = 1; return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { if (x > 8) { x = 0; } if (x <0) { x = 8; } if (y > 20) { switch (boxType) { case 0: SaveBoxI(); break; case 1: break; case 2: break; } y = 0; boxType++; if (boxType > 2) { boxType = 0; } } this->WriteBox(); return TRUE; } BOOL OnKey(WPARAM wParam) { if (wParam == VK_LEFT) { x++; } if (wParam == VK_RIGHT) { x--; } return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { MyWindow *target = MyWindow::find(hWnd); target->OnKey(wParam); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
テトリス風
落ちてくるブロックの描き方
まずはブロックの種類は3種類
の違いをよく見比べて
自力で違いがわかれば
プログラマーにはなれるとおもう
とはいえ、コレを自力でわかるならもっと儲かる仕事あるとはおもうけどな
BOOL WriteBox() { switch (boxType) { case 0: return WriteBoxI(); case 1: return WriteBoxL(); case 2: return WriteBoxZ(); } }
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); x = 0; y = 0; boxType = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int x; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48*9,48 * 8 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } int boxType; BOOL WriteBox() { switch (boxType) { case 0: return WriteBoxI(); case 1: return WriteBoxL(); case 2: return WriteBoxZ(); } } BOOL WriteBoxZ() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxL() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) -1 ; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) -1; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.left += width; Rect.right += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL WriteBoxI() { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); int width = 24; RECT Rect = { 0,0,48,48 }; BOOL ret; Rect.left = width * x + 1; Rect.right = width * (x + 1) - 1; Rect.top = width * y + 1; Rect.bottom = width * (y + 1) - 1; ret = FillRect(hdc, &amp;Rect, hBrush); //Rect.left += width; //Rect.right += width; Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); Rect.top += width; Rect.bottom += width; ret = FillRect(hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { if (x > 8) { x = 0; } if (x <0) { x = 8; } if (y > 8) { y = 0; boxType++; if (boxType > 2) { boxType = 0; } } this->WriteBox(); return TRUE; } BOOL OnKey() { x++; return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { MyWindow *target = MyWindow::find(hWnd); target->OnKey(); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
第何回だろうな
まだ、何を押してもブロックが右に移動するだけ(右端にいくと左にワープ)
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); x = 0; y = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int x; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48*9,48 * 8 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); RECT Rect = { 0,0,48,48 }; Rect.left = 48 * x; Rect.right = 48 * (x+1); Rect.top = 48 * y; Rect.bottom = 48 * (y+1); if (x > 8) { x = 0; } if (x <0) { x = 8; } if (y > 8) { y = 0; } BOOL ret = FillRect(ps.hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } BOOL OnKey() { x++; return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_KEYDOWN: { MyWindow *target = MyWindow::find(hWnd); target->OnKey(); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); y = 0; hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL run; int y; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); run = true; int rc; // メイン メッセージ ループ: while (run) { DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL, 100 , QS_PAINT| QS_ALLEVENTS,0); if (obj <= WAIT_OBJECT_0) { while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } if (msg.message == WM_QUIT) { run = FALSE; } if (msg.message == WM_CLOSE) { run = FALSE; } } } else if (obj == WAIT_TIMEOUT) { y++; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); this->OnPaint(ps); EndPaint(hWnd, &amp;ps); ::UpdateWindow(hWnd); RECT Rect2 = { 0,0,48,48 * 8 }; InvalidateRect(hWnd, &amp;Rect2, TRUE); } else if (obj == WAIT_FAILED) { rc = GetLastError(); } else { } } return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { HDC hdc = GetDC(hWnd); HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); RECT Rect = { 0,0,48,48 }; Rect.top = 48 * y; Rect.bottom = 48 * (y+1); if (y > 8) { y = 0; } BOOL ret = FillRect(ps.hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
青い■を表示するだけ
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); // メイン メッセージ ループ: while (GetMessage(&amp;msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } } return TRUE; } BOOL OnPaint(PAINTSTRUCT &amp;ps) { HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246)); RECT Rect = { 0,0,48,48 }; BOOL ret = FillRect(ps.hdc, &amp;Rect, hBrush); DeleteObject(hBrush); return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(ps); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
次の解説
staticキーワードを付けることで
これでHWNDを通して
static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; }
// WindowsProject7.cpp: アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include "WindowsProject7.h" #define MAX_LOADSTRING 100 // グローバル変数: HINSTANCE hInst; // 現在のインターフェイス WCHAR szTitle[MAX_LOADSTRING]; // タイトル バーのテキスト WCHAR szWindowClass[MAX_LOADSTRING]; // メイン ウィンドウ クラス名 // このコード モジュールに含まれる関数の宣言を転送します: //ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); #include <list> class MyWindow; std::list< MyWindow *> windows; class MyWindow { public: HWND hWnd; MyWindow() :hWnd(NULL) { windows.push_back(this); } virtual ~MyWindow() { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { if (*it == this) { windows.erase(it); break; } } } static MyWindow * find(HWND key) { std::list< MyWindow *>::iterator it; for (it = windows.begin(); it != windows.end(); it++) { MyWindow *target = *it; if (target->hWnd == key) { return target; } } return NULL; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&amp;wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: インスタンス ハンドルを保存して、メイン ウィンドウを作成します。 // // コメント: // // この関数で、グローバル変数でインスタンス ハンドルを保存し、 // メイン プログラム ウィンドウを作成および表示します。 // BOOL InitInstance() { hInst = hInstance; // グローバル変数にインスタンス処理を格納します。 ATOM c = MyRegisterClass(hInstance); hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } return TRUE; } BOOL ShowWindow() { BOOL ret; ret = ::ShowWindow(hWnd, SW_SHOW); ::UpdateWindow(hWnd); return ret; } HINSTANCE hInstance; MSG msg; BOOL Main() { HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7)); // メイン メッセージ ループ: while (GetMessage(&amp;msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } } return TRUE; } BOOL OnPaint() { return TRUE; } }; int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: ここにコードを挿入してください。 // グローバル文字列を初期化しています。 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING); //MyRegisterClass(hInstance); MyWindow win; win.hInstance = hInstance; // アプリケーションの初期化を実行します: if (!win.InitInstance()) { return FALSE; } BOOL ret; win.ShowWindow(); ret = win.Main(); if (ret) { return 0; }else { return (int)win.msg.wParam; } } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &amp;ps); MyWindow *target = MyWindow::find(hWnd); target->OnPaint(); // TODO: HDC を使用する描画コードをここに追加してください... EndPaint(hWnd, &amp;ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // バージョン情報ボックスのメッセージ ハンドラーです。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }