はてなキーワード: インターフェイスとは
金が無いくせに口だけ達者
片手で操作できる大きさ→大抵出来る
もたつかない待たせないスムースなタッチインターフェイス→出来るのに何を?
イヤフォンジャック付きで音楽聴きながら充電できる→おくだけ充電使えよ
一日中動画やゲームやっても帰宅までもつバッテリー→持つ。持たないのは使い方が悪い
インスタ映えとかどうでもいいから昼間ならきれいに取れるカメラ(画像はアプリで自分で修正すればいい)→あるだろ
アップデートが安心してスムーズにできる(Androidみたいに機種によってアプデ時期がバラバラとか論外)→できるけど。スマホに通知くるだろ。
別にそこまで薄くなくていいから100グラムちょい程度の軽さ→今までのスペック上では無理だろ。お前がたくさん金払うなら可能だろうが
ここ連日騒がれている7pay。
パスワードリセットリンク送付先のメールアドレスに対して設計上の問題で脆弱性が発覚して大変な事態に発展しています。
昨日の会見では社長のITリテラシ不足が露呈したり、サービス継続が表明されたりして、いわゆる「祭」の様相を呈しています。
また、会見内で「セキュリティー審査を実施した」と明言がされました。
https://www.asahi.com/articles/ASM745HHHM74ULFA01Y.html
セキュリティー審査を実施していたにも関わらず、何故今回の問題が見逃されたのか。
非常に稚拙な推測ですが個人的に考えられる可能性をまとめてみようかなと思います。
その名の通り、サービスローンチ前に実施する、脆弱性や問題がないかの審査の事・・・だと解釈しました。
一般的には脆弱性診断とかセキュリティ検査とも呼ばれています。私はこちらの呼び方の方がしっくりきます。
「実施した」とはいっても、どういった内容を実施したかはわかりません。
ただ、7payは「一般に公開する」「お金を扱うサービス」になるため、ガチガチな脆弱性診断を実施すべきでしょうし、実際に実施したのではないかと思います。
通常、脆弱性診断というと、以下のような項目があげられると思います。
抜け漏れあると思うけど、大体どこのセキュリティベンダーでも上記のような項目を診断しているんじゃないかなあと思います。
詳しくは各ベンダの診断内容のページを見てみると更に詳しく載っています。
LAC、CyberDefence、NRIセキュア、ブロードバンドセキュリティ、スプラウトなど。
ただ、今回の脆弱性診断が外部ベンダで実施されたのか、内部で実施されたのかはわかりません。
以下、推測をつらつら書いていきます。
脆弱性診断はモノによりますが、診断内容をマシマシにするとエラい額が掛かります。
Webサービス診断は見積もり方法が各社違ったり、ツールを使うか手動とするかによって金額も大きく変わってきます。
また、数量計算もベンダによってまちまちです。ページ単位であったり、画面遷移単位であったり、SPAであればAPI単位であったり、複合での計算だったりします。
お願いすれば見積もり時にステージング環境で動いているWebサービスをクロールして、各ページの評価を付けてくれるベンダもあります。
規模と見積もり内容にもよりますが、100~200万といったところでしょうか。
スマホアプリ診断は一本幾らという場合が多いような気がしますね。相場としては50万~100万程度でしょうか。
プラットフォーム診断も内容によるとは思いますが、大体100万くらいかなあと思います。
これ以外にWebSocketを使っていたり、別のサービスと連携していたりするとその辺りの通信も含まれてくるのでまた金額は上がる可能性もあります。
Webサービス200万、スマホアプリ(iOS、Android)100万*2、プラットフォーム100万とすると、500万円掛かるわけですね。
脆弱性診断をするだけでこれだけのお金が吹っ飛んでしまうわけです。
そしてこれをそのまま発注するかと言われると、多分しないでしょう。
セキュリティはお金が掛かる割にリターンが少なく、目に見える結果が必ず出てくるとも限りません。
経営層は中々首を縦には振らないでしょう。
会見でも明らかになったことですが、社長のITリテラシはあまり高そうにありません。
こうなると脆弱性診断の稟議を通すのは中々容易ではなかった可能性もありそうです。
また7月1日に間に合わせたようなところもあるっぽい(?)ので、開発側に資金を全振りしていた可能性もあり、診断に費用を掛けられなかったのかもしれません。
いずれにせよ、全く実施しないのはまずいし重要そうな部分だけピックアップして実施しましょうという話にはなるでしょう。
削れるものをあげていってみましょう。
例えば、iOS用スマホアプリは実施しなくても良いかもしれません。iOS上で動くアプリは確かサンドボックス構造になっているはずで、ローカルに何かしらのデータを持っていても外部からのアクセスは基本不可であるためです。確か。
そもそもスマホアプリ自体不要かもしれません。7payのサービスへのアクセス用インターフェイスとしてのアプリしか提供していないのであれば、取り扱うデータはほとんどないと考えられるためです。そのため、スマホアプリAndroidのみ、もしくは両方実施しなくても大きな問題は発生しないのではないかと思います。
・・・この辺り私の勘違いというか、「最優先でやるべきだろjk」といった考えがあれば指摘ください。
プラットフォームも、ベンダによりますが実施しなくとも良いとも思います。
ベンダの説明でも、主にポートスキャンをして、空いているポートに対してtelnetで色々したりするといった説明がなされたと思います。
Webサービスなら443と、空いていても80くらいしか外部には公開していないので、これは実施しないという選択をしても不思議ではないと思います。
サーバのコンフィグも、DocumentRootがおかしいとか致命的な設定ミスをしていない限りは見てもらう必要はないでしょう。
そもそも構築手順等はノウハウもあるでしょうし、わざわざ見てもらう必要性はほとんどないわけです。
ワイドショーでは「不正は海外IPからで、国外からのアクセスを許可していた」事が取り上げられていましたが、例えプラットフォーム診断をしていても、この辺りは指摘されなかった可能性があります。
実施していればもしかしたら備考レベルでの注意や、口頭で「国内のみに留めておいた方がいいかも」といったことは伝えられたかもしれませんが、「利便性」という観点から実行されることはなかったんじゃないかなと思います。
Webサービスですが、ログイン・ログアウト処理は必須でしょう。また、新規登録、情報変更、退会処理も重要です。
パスワードリセットはどうでしょうか。正直これも重要です。なので、ベンダに依頼するにあたってはここも診断対象としていたはずです。
ところで今回の件では協力会社について様々な憶測が飛んでいますが、NRI説が結構人気みたいです。
ただ、NRIにはNRIセキュアというセキュリティに特化した子会社が存在しています。
もし脆弱性診断をするとなった場合、そこを使わないという手はあまり考えられません。そもそも発注時にそれを見越して診断費も開発の見積もりに含まれているのではないかと思います。
ただし、セブン側が「脆弱性診断はこちら側で発注します」と言っていれば話は別です。
NRIセキュアは診断費用が高いらしいので、コストダウンするために別ベンダに診断部分のみ発注する可能性はあります。
別のベンダに発注したことで、抜け落ちた可能性はゼロではないかもしれません。
また、NRIセキュアが実施する場合においても、「ここは抑えておいた方が良い」という機能毎やページ毎にランク付けした資料をセブン側に提出することと思われますが、どこを実施してどこを削るかの最終的な判断はセブンに委ねられます。
考えられる事としてはパスワードリセットの処理を診断対象外としたことですが・・・そうする理由もわからないので、うーん・・・。
ただ、こうして対象を削りまくることで100万程度、もしくはそれ以下まで診断費用を抑えることができます。
使ったことはありませんが、SecurityBlanket 365というサービスは自動での定期診断が可能なようです。
ライセンスやどういった動き方をするのかはいまいちわかりませんが、ベンダに逐次依頼する脆弱性診断よりかは安く済むはずです。
ただ、自動診断となると設計上の不備やそれに伴う問題は検出できないはずです。
ツールの手が届く範囲での、XSSやPoC、ヘッダの有無など、ごく一般的な脆弱性診断になると考えられます。
でも手軽そうで安価っぽいなので、これで済ませていても不思議ではないです。
脆弱性診断ツールはOSSのものもあればベンダが販売していたり、SaaSで提供しているものもあります。
OSSならOWASP ZAPやw3afがWebサービスの診断が可能です。また、phpcs-security-auditなど、ソースコードを解析し脆弱な箇所がないかを診断するものもあります。
ちなみにWebサービスに対する診断を「DAST」、ソースコードに対する診断を「SAST」と言ったりします。
有償のものとなると、DASTは先程のSecurityBlanket、AppScan、Nessus、Vex、VAddyが挙げられると思います。
SASTになると、RIPS TECH、Contrast Securityなどでしょうか。
上記のようなツールを用いて、セブン内で脆弱性診断を実施することでセキュリティの知見を高めたり、内部で完結させるための動きを取っていたかもしれません。
こういった動きは結構色んな組織で見受けられます。外部の手を借りずに診断ができれば、関係者間の調整も楽ですし、それと比べると費用も安く済みますからね。
ただし、社内のエンジニアに任せる事になるため、片手間になってしまう可能性があります。
また、ツールの使用方法についてのノウハウは溜まるかもしれませんが、それとセキュリティの知見が溜まるかどうかは別の問題としてあると思います。
・・・とは言ってもセブンにはCSIRT部隊がちゃんとあるんですよね。
https://www.nca.gr.jp/member/7icsirt.html
『7&i CSIRT は、7&i グループの CSIRT として設置され、グループ企業に対してサービスを提供しています。』と記載があります。
また、『7&i CSIRT は、7&i HLDGS. の組織内に専任要員を以て設置され、インシデント発生時の対応だけでなく、インシデント発生の未然防止にも注力しています。
グループ企業の情報システム部門と連携し、7&i グループ内で発生するインシデントに対する未然防止のための調査・分析とリスク情報の共有、ならびにインシデント対応活動を行なっています。』
という記載もあるため、今回の7payも、7&i CSIRTが動いてセキュリティ関連のチェックをしていたのではないかと思います。「情報システム部門」とはありますが。
組織図上にはありませんが、デジタル推進戦略本部の下か、リスクマネジメント委員会、情報管理委員会のどこかに所属しているんじゃないかと思われます。
日本CSIRT協議会にも名を連ねているわけですし、CSIRTメンバーは専任要因ともありますし、セキュリティ関連の技術知識は十二分にあると思うんですよね。
なので、内部でツールを使って実施していたからといって、こんな重大な不備を見逃すというのはちょっと考え辛いなあ・・・と思います。
会見内で言われた二段階認証も検討事項に上がらなかったのかなあ・・・と。
で、これを書いている最中に気付いたのですが以下のようなリリースが出ていたんですね。
https://www.7pay.co.jp/news/news_20190705_01.pdf
これを見ると内部のCSIRTが機能していなかったか、力不足と判断されたかどちらかになるのかな・・・と。
実際はどうだかわかりませんけど・・・。
これも有り得る話かなあ・・・と。
開発やベンダやCSIRT部隊が情報共有したとしても、POが忘れていたとか、伝えたつもりが曖昧な表現で伝わっていなかったとか・・・。
ベンダが実施して指摘事項として伝えていたけど、いつの間にやら抜け落ちていてそのままサービスイン・・・というのもシナリオとしては考えられますね。
7payは社内的にも一大プロジェクトだったはずで、スケジュールも決まっている場合、余計なことを物申すと手戻りや対応に時間を取られることになります。
そういった事を許さない空気が出来上がっていると、まあ中々上には上がってきづらいです。
これも十分にありえる話ですかね。ないといいんですけど。
どうしても『審査』という言葉に引っかかっています。『検査』ならまだわかるんですが。
そこで思ったのですが、情報セキュリティ基本方針と個人情報保護方針を元にしたチェックリストのようなものがセブン内にあって、それを埋めた・・・みたいなことを「セキュリティー審査」と言っていたりするのかなと思ってしまったんですね。
でもこれはセブンペイの社長が個人情報保護管理責任者ということで、ISMSやPMS等で慣れ親しんだ単語である『審査』を使っただけかもしれません。
そもそもそれで終わらせるなんて事ないでしょう。セブン程の企業が・・・。
大穴ですね。いやこれはないと思いますよ。あったら大問題じゃないですか・・・。
というわけで、なんとなく「こうだったりして・・・」みたいな事をつらつら書いてみました。
そういえばomni7で以下のお知らせが上がっていましたね。
https://www.omni7.jp/general/static/info190705
『定期的にパスワードを変更いただきますようお願い申し上げます。』とのことです。CSIRTはもしかしたらもう機能していないのかもしれないですね。
もしくはわかりやすい対策を提示しろと言われたのかもしれません。それなら仕方ないんですけど。
以上。
一部typoとか指摘事項を修正しました(役不足→力不足 etc)。
ついでに時間経ってるけど追記します。もう誰も見ないでしょうけど。
ちゃんと読んでいただけましたか?全文通して私の主張が「監査をしっかりやれば防げた」という意味と捉えられているのでしょうか。そんなに分かりづらい文章を書いた覚えもないのですが・・・。
一番上でも記載していますが、私は今回の7payの「セキュリティ審査」は、「脆弱性や問題がないかの審査の事」、つまり「脆弱性診断」を指していると仮定して本エントリを書いています。
そういう意味で、ここで私が指している「審査」と貴方が指している「監査」は似て非なるものです。字面は少し似ていますがね。
監査は貴方の記載する通り「ある事象・対象に関し、遵守すべき法令や社内規程などの規準に照らして、業務や成果物がそれらに則っているかどうかの証拠を収集し、その証拠に基づいて、監査対象の有効性を利害関係者に合理的に保証すること」です。
貴方の言う「監査」に近いことは「セキュリティー審査自体が、情報セキュリティ基本方針と個人情報保護方針に沿った内容かどうかを確かめただけだった」の見出し部分で触れていますが、それで終わらせているわ Permalink | 記事への反応(2) | 05:48
MacBook Pro辞めて、Mac Pro買おうかなと思っていたが、いよいよMac熱が冷めた話をしてみたい。
10年から5年前くらいまでのMacBook Proは、先進的で、Appleの拘りに共感でき、さらにコスパもそこそこだった神製品だった。
ところが、今は、強豪がかつてのMacに追いつき、Appleの拘りにも共感できず、一般的なサラリーマンにはちょっと手が出ない価格帯になってしまった。
私はWeb開発をしていて、サーバー用OSであるUNIX系のソフトを利用することが多い。MacもまたUNIX系のOSであるため、Web開発の相性もぴったりだった。
Text MateというMacでしか動かないエディタが存在した。私はMacをこのText Mateのために購入したと言っても過言ではない。Windowsにも似たような製品はあったが、Text Mateの使いやすさには及ばなかった。
あとは、それまで利用してたWindowsのソフトのMac版が用意されており、Windows同等に利用できたことも大きかった。
Web開発の主流は仮想化((Dockerが3位。https://insights.stackoverflow.com/survey/2019#technology-_-platforms))。中でもコンテナ型のDockerを使うことが多くなってきた。しかしながら、そもそもLinux上で動かす用途なので((と勝手に認識していますが))、Windows版とMac版は速度に難があり。Docker使うの辞めた人もいるくらい((https://shinkufencer.hateblo.jp/entry/2018/05/03/233000))。私も5年前のマシンで不自由してなかったけど、Dockerだけ実用速度が出ないときがあって困った。
WindowsもUNIX系のソフトを利用しやすくするため、「Windows Subsystem for Linux」といったものを標準で組み込んできた。今度登場する「Windows Terminal」はSSHを利用できるみたい((https://www.itmedia.co.jp/news/articles/1905/07/news080.html))。
Macでしか利用できないText Mate以外にも便利な開発ツールが登場した。Visual Studio CodeやIntelli J((10年前にもあったけどな))など。どちらもWin版だけではなくLinux版に対応している。
Macが高いかどうかは議論の余地があるが、Macには選択肢がないってところが大きいかな。
Windows機みたいに5万円切る安いMacも無いし、メモリー増設も出来ないくらいメンテナンス性が落ちていると聞くし。
うちの会社はご多分に漏れず零細ITなのだが、作ってるアイポンのアプリをダークモードにしようかという話が出ている。こないだのあれでそういう機能がついたからね。インターフェイススタイルとか言われてんのかな、知らんけど。
でもやっぱ対応するのに工数はかかる。今までそんな事考えずにやってきたアプリだとなおさらだ。だからこの機能を有料機能の一つにしちゃわない?という話になっている。
大丈夫なのかな。いや多分審査的には問題ないんだろうけど、世の中的にさ。「ダークモードは福祉!有料なんて反社会的だ!よくも偏頭痛を悪化させてくれたな!星1つ!」みたいなレビューで埋まったらどうする。こわいよ。
先進国でも、発展途上国でも、みんながこのハイテクな板切れに夢中だ。
スマートウォッチ!スマートグラス!スマートスピーカー!スマート冷蔵庫!
「さぁ、君もスマート○○を手に入れて、もっとスマートになろう」
現代社会は、賢くなければ生き残れない。
スマートデバイスの代表例と言えば、やはりスマートフォンだろう。
スマートフォンはフィーチャーフォン(ガラパゴス・ケータイ)と比べて、どこがスマートなのか?
スマートフォンが登場した当初は既存のケータイと比べて「パソコンライク」に扱える印象があった。
パソコンのようにサイトを見ることができ、パソコンのようにマウスやキーボードを接続でき、パソコンのようにファイルにアクセスができる。
フィーチャーフォンはそれらのことが(基本的に)出来なかった。
「ケータイはパソコンに著しく劣る」という前提からのスマートフォンなのである。
比較的知名度の高いスマートウォッチやスマートグラス、スマートスピーカーであるがスマートフォンほどはヒットしていない。
スマートウォッチやスマートグラスは、まぁスマートフォンの周辺機器のようなものだ。
(スマートグラスに至っては盗撮問題が解決されない限り普及は困難だろう)
スマートスピーカーは主に裕福層<ブルジョワジー>や最先端技術愛好家<ギーク>が愛用しているにとどまるようだ。
(裕福層は豪邸に住んでおり手足を使わずにスイッチを音声コントロールするためスマートスピーカーを買う)
スマートデバイスは無数にあるが大成功といえるのは実質スマートフォンぐらいではないか?
他にはスマートフォン人気にあやかった周辺機器がそれなりに売れている程度だろう。
例えばドローン、HMD(ヘッドマウントディスプレイ)、VRヘッドセット、3Dプリンタ、ロボット掃除機、シングルボードコンピュータなどが挙げられる。
安易にスマート○○と名づけてしまうのは方向性が明確でないためではあるまいか?
スマートデバイスのネーミングについて考えているうちに思ったことがある。
実はスマートフォンは、他のスマートデバイスと比べても特異なのではないか?
スマートフォン以外のスマートデバイスは「非コンピュータ搭載」→「コンピュータ搭載」というコンセプトのものが多い。
しかしスマートフォンに限って言えばフィーチャーフォンもコンピュータ(SymbianOSなど)には違いなかったはずだ。
(なおガラケーが本当コンピュータなのかについては知識不足により掘り下げて説明することができない)
スマートデバイスの代表例スマートフォンは、しかしスマートデバイスの中でも特異なのである。
思いついたスマートデバイスは大抵もうある。
スマートペン。スマート義肢。スマートカー。スマートバイク。スマートエレベーター。スマート監視カメラ。スマートインターホン。スマートドラッグ。スマートダスト。
傍から見るとあらゆる業界の開発者がスマートな使命感に燃えているようである。
それにしても製品を作っている当の本人たちは本当にヒットすると思っているのだろうか?
あるいは「これからはスマートの時代だ。IoTの時代だ」という有難いアドバイスのおかげかもしれない。
スマート○○を名乗れるのは早い者勝ちで最初のひとつだけなのである。
最初のひとつがスマート○○をうまく解釈して、うまく顕在化させて、うまくアピールできればヒットする可能性はある。
しかし、いまいちシックリこないものが最初にスマート○○を名乗ってしまえば、そこでおしまいだ。
先に商標などを押さえられてしまえば後続者は身動きが取れない。
新しいスマートデバイスのコンセプトとして、既にあるものをスマートにする方向性は厳しいように思える。
なぜならコンピュータを搭載しないで普及したものは、コンピュータを搭載しないでも普及できたためだ。
もし成功するスマートデバイスがあるとするなら、それは恐らくコンピュータを搭載しないと実現できないものだろう。
個人的には「スマートフォンを制御モジュールとしてドッキングする製品」という方向性にシフトしていくと予想する。
規格化されたスマートフォンスロットがあり(ファミコンカセットみたいに)スマートフォンを差し込むことで機能をゲットできるという仕組みだ。
(オーディオインターフェイスやスピーカーなどのジャンルでドッキングする製品はすでにある)
スマートデバイスはスマートフォンの一強だということに、みんなそろそろ気づくだろう。
スマートフォンがすごいのならスマートフォンとひとつになればいいというわけだ。
眠れない夜キミのせいだよ~
はじめての生体認証!
つい先日近郊の銀行で口座を開設したのよ。
張り切って行った
生体認証したときは暗証番号いらないのね!とビビってしまったわ。
暗証番号無しで引き出せるって、
ヤバくない?危なくない?大丈夫なのかしら?って思うわ。
もうさ、
いつまで人類は
信号の画像をクリックしたりしなきゃいけないのよ!と面倒くさいなぁと思ってたら、
あの暗証番号入れてないのに開けちゃったんですけど!って言いそうになったわ。
これちゃんと動いてるのかしら?って思うし。
指をスキャンしたら
黒い画面に無駄にデカデカと緑色のワイヤーフレームで表示されくるくる回る指先のイメージが出てきて、
赤い丸がぽわんぽわんと点滅表示されて、
リアルタイムにコンピューターが考えて認証してるんだな感を表現している、
そんなの現実の生体認証での画面では一度も見たことないわ!ってぐらい
映画を見てる人に分かりやすいぐらい大袈裟な大風呂敷演出の生体認証システムな画面だったら
フォント大きいし
インターフェイスの作りもなんか大きいし、
全てのスケールがなんか大きいのよね。
そんなの今時Windowsでもないわよ!って思っちゃうぐらい。
チャンチャン。
なんか今日はお店の品揃えが冴えない感じね。
すいすいすいようび~
今日も頑張りましょう!
// 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; }
// 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; }
// 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); class MyWindow { public: HWND hWnd; MyWindow() :hWnd(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; } }; 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); // 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; }
こんなかんじ。クラス化した