はてなキーワード: インスタンスとは
取り敢えずmstdn.jpを使っておけば良いと思う
MastodonにはTwitterが過去持ってた機能のUserStreamsに該当するlocal Timelineがあるから、mstdn.jpで「音楽趣味なんだけどそれにあったMastodonインスタンスある?」とか「ガジェット好きなんだけど良いMastodonサーバーある?」とかある程度の情報を載せて質問すると、mstdn.jpのユーザーの誰かが丁寧に教えてくれると思うぞ
mstdn.jpの性質として2ちゃんねるでいうところのラウンジ板とか初心者の質問板のような役割を持っている
自身でMastodonインスタンスを運営したい場合もmstdn.jpで質問をすると既にインスタンスを運営している管理者を紹介してくれたり、インスタンス管理者自身がリプライしてくるはずだから質問すると良い
ぶっちゃけタルいのがすげー嫌。
Oracle DBの使い方を習得するのに、一番最初に用意すべきなのはパソコンでもサーバでもない。
その教科書で、まずはスキーマやインスタンスやアーカイブログやREDOログといった、Oracle DBの仕組みや概念を学習する。
次にそれが実際のサーバ上でどんな風に見えていて、どうオペレーションするか…というアプローチを取らないと、絶対に動かないようにできている。
あーもうすげーめんどくせー。
なんでこんなにもったいぶっていて、無駄に固いんだか。覚えにくいことこの上ない。
それに比べると、PostgreSQLはフリーソフトなのに本当によくできている。
無駄な前置きは一切なしで、実際にいじりながら覚えていけるのでハードルが超低い。
てか、こういうのでいいんだよこういうので。
そもそもOracleのような「教科書と授業」みたいな形式で覚えてくのって、ストレージやアプライアンスを扱うのも仕事のうちという構築や運用の人間ならともかく、プログラマにとっては全く水が合わない。
だってCOBOLやFortranが主流だった大昔ならいざしらず、開発の世界じゃそういうのはC言語が出た時点で時代遅れになってるから。
まじで勘弁してほしい。
https://ja.wikipedia.org/wiki/W3m
昨今のサイトを見るにはとても不便で、操作性も何もかも非効率だけども、ブラウジングがとても新鮮なものになるよ
CDが売れなくなっている昨今、EP、LPとかレコードは好調らしい。
なんかそんな記事を見た中に、
「もはや音楽を聴くことに娯楽的意味がなくなってしまい、CDセールスが衰退、アーティストが音楽のみで身を立てることが困難になっている中で、
ライブに行き生演奏を目で体で聴くことで原初的感動を受ける人や、繊細なアナログメディアで音楽を享受する”儀式的行為”により、新しい価値を見出している人がいるため」
というようなことが書いてあって、なるほどなあと思った。
効率を無視した献身的行為、ある種の狂信とも言うべき自慰的な活動こそが、拡散してしまいがちなアイデンティティを収斂するための一助になっていると考えているので、
それが音楽であれ、ピュアオーディオであれ、ルリ儀式、筋トレ、政権批判、ガチャ課金、なんにでも没頭できるものが見つかるということはとても喜ばしいと思う。(誰かに迷惑をかけなければ)
音楽ほど歴史が長くないが、Webブラウザも年々大きく変動している最中で、研究者のツールだったものが大衆向けに整備され、一般化されるコンテンツに合わせてWWWの利用も複雑化している。
SNSと高度に連携したスマホファーストの無味乾燥に大量消費されるコンテンツを見ていると、WWWを見るという行為を愛で、儀式的行為に価値を見出しても良いように思う。
「インターネットを介したコミュニケーションでは情報が多すぎる、たくさん情報を受け渡しすると疲弊する。
情報量を極限まで削ることで、原初的な伝わったことが嬉しいという気持ちを得られる。
ここからw3mで適当にWebブラウジングをするのが習慣になった。
原理主義というならLineModeBrowserとかLynxとかを選ぶべきなのだろうが、
日本発というアニミズム的発想(とドキュメントの多さ)からW3mを選んだ。
何よりも、w3mは「WWW-wo-Miru」の略だというと、上にあげた「WWWを見る」という行為に儀式的意味を持たせるためには必要な要素だと思われた。
最近だとBrow.shという画像も何とかテキストで表示してやろうという意欲的なものもあるんだけども、これは端末の解像度に依存が大きいため断念。
というか画像も必要であれば普通のブラウザ環境も使うという腥っぷり。
twitterは、twtermを使ってこれも余計なTLチェックが不要となった。
というような落書きを、適当なEC2インスタンス上のw3mから書いている。
EC2にtmux + w3m + twterm という環境をほぼ放置してあり、コマンド一発でほぼ同じ環境を無料AWSを乗り継いで利用できるようにしてある。
はてブをテキストベースで閲覧する方法を探している。それがあれば、より原初的感動を持ってクソのようなコメントを投げ合えるパラダイスが待っていることは自明である。
くそ長い話なので注意
最近、TwitterでロリキャラのR18イラストを描くアカウントへの規制が厳しくなってきたらしい。
そういったアカウントの凍結は前からあったが、最近は特に見つかり次第凍結されている印象だ。
ぶっちゃけてしまうと私はそういうイラストが好きなので、個人的には少し残念な状況ではある。
ただ、だからといって「表現の自由を守れ!」なんてTwitter社にケチをつけたいとは全く思わない。
みんな知ってる通り、日本という国はロリエロ絵に対する規制がかなり緩いが、世界的に見れば法律でNGとしている国も少なくないし、国際的な流れは完全に規制寄りだ。
そんな状況では、いくら日本人ユーザーが多いTwitter社でもロリエロ絵を看過できなくなって当然だと思う。
さて、それではそもそも、ロリエロ絵がTwitterなどのSNS上で投稿・拡散されることの問題とはなんだろう。
ロリコンが増えることも社会的にはマイナスではあるが、これについては言論・思想の自由で見逃されていい範囲だと思う。社会的にプラスな思想のみ肯定する世界になったら、それは単なるディストピアだ。
なので、間違いなく一番問題なのは「見たくない人の目に触れてしまう」ことだと思う。
すこし前に話題になった「お父さん、あれ気持ち悪い」発言だって、見たくないのに目に入ってしまうのが原因だし、他の既出の問題もたいていここが原因だろう。
これの対策は一見すると簡単で、「見たくない人が見ないところで投稿・拡散すればいい」という「自主ゾーニング」なのだけど、私の知っている限りこの試みは何度も失敗している。
これまで何度も、ロリエロ絵のイラストレーター達は「Twitterではやってられない! Pawoo(Pixivが運営するMastodonのインスタンス。Twitterに似ている)に移住しよう!」と発言しているのだが、まあ十中八九失敗している。
なぜかと言えば、Pawooはユーザーが圧倒的に少なく、絵を多くの人に見てもらえないからだ。
クリエイターにとって知名度こそ全てだ。知名度だけ高ければいいわけでもないが、知名度がなければ何もできない。そして、それはロリエロのイラストレーターも例外ではない。
というわけで、結局彼らは絵に修正を入れたりリンクを貼ったりして、だましだましTwitterで活動し続けている。
とまあ、ここまで書くと「そんなもん描くやつ勝手にくたばればいいだろ」と思う人が多数派だろう。
まあその通りなんだけれど、ちょっとだけ待ってほしい。
上で書いたとおり、ロリエロ絵の最大の問題は「見たくない人の目に入る」ことで、それさえ無ければ被害者はいなくなる。
だから、ゾーニングさえ上手くできれば(ほぼ)問題はないのだ。
ではロリエロに限らずweb上で、「見たい人にはちゃんと届くように」「見たくない人には届かないように」上手くゾーニングするにはどうすればいいんだろう。
私は「webブラウザ、検索エンジンを提供する企業が、最初にユーザーに見たくないものを選択させ」、「Twitterなどのサービス提供者が連携する機構を作り」、「投稿者がきちんとカテゴリを選択して投稿する」ことでしか解決できないと思っている。
例えば、Google Chrome(ブラウザ)のインストール時、ユーザーに「ポルノ」「暴力」など見たくないものを選択させる。
Twitterはそれに対応するカテゴリの選択肢を作り、投稿時などに選択できるようにする。
そして投稿者が「ポルノ」にチェックをつけて投稿すれば、ポルノを見たくない人には届かないといった寸法だ。
そして、これらのルールを破ったユーザー、サービス提供者には即座にペナルティを課すようにする。
大仰なやり方ではあるが、web上のゾーニングはロリエロだけでなく大きな問題なのでこれくらいやってもいいんじゃないかと思っている。
そして、この仕組みを作れるのは世界中のwebを席巻しているGoogleくらいじゃないだろうか。
…というわけで、Googleさん、そろそろ(誰も不幸にならない形で)ゾーニングに本気出してください。
お願いします。
はい。
これが言いたかっただけ。
優れた記事。中央集権化と分散化の流れは、振り子のように行ったり来たりするもの。今後しばらくは分散化の方向なのかもね。でも、mstdn.jpの例のように、おそらく自動的に一極集中が進む気もする。
こんなんプロトタイプだろ。ニーズがあって注目されれば、ソースも構造もどんどん改善されて行く。まず、情報インフラはTwitterじゃなくてもいいんだ、自分でも運営できるんだ、ってことが皆に浸透したことが画期的。
これは非常に正しい。自前の鯖を立てることにしよう。
マストドンは愛すべきサービスだが、今のままではとても流行るとは思えない。「インスタンスを選ぶ」の時点で、一般人の8割が脱落する。例えばLINEが最初にサーバを選んで始める仕組みなら、こんなに普及してないよ。
マストドンが流行ってます、とか語りつつ使ってなかったり、使わずに大したことないとか言ってるWeb業界人が本当に意味不明。インスタンス運営は知識や覚悟が必要だが、1分で出来るユーザー登録を何故やらないのか。
俺は、国内最初のMastodonオフ会を自社オフィスで開いて以来、Mastodon会議に参加してヌルカル氏、清水氏、江添氏その他の話を聞くまではヘビーユーザーだったが、これはスケールしないな、と確信したので常用を辞めた。
アカウントの完全削除処理って地味に影響範囲が大きいからほとんどのサービスは利用凍結くらいで止めてるんだけど、マストドンで実行すると他のインスタンス横断のデータ処理になるので、マジで恐ろし過ぎる。
はてブの投稿連携ができたら、もっとMastodonも使うんだけどなー。俺にとってNo. 1のソーシャルメディアは、はてブだからなー。
これは乗るべきか乗らざるべきか迷うなあ。GAFA以外の次世代の有力サービスが軒並み参画して流れがこっちに向けば普及するかもしれないが、そうでなければMastodonレベルだろう。とりあえず仕様を確認してみよう。
当時からMastodonの行く末を予想してツイートしてたが、予想通りすぎる。結局、スケールできないSNSは廃れるんだよ。どう考えても、10万以上のユーザーを抱えるにはコスト的に見合わない。
もしかしたら最近の人はバトロワがMMOではない事が理解できんのかもしれんな。
あれらはいわば、1ルームが100人くらいのMOFPSで、マッチごとにマップのインスタンスが作成される形なんだけど、
やっぱり途中で切れたので続きから
違います。
そうです。
はい。Stadia Games and Entertainmentの組織を発表しました。これは我々の1stパーティのスタジオです。
はい。
Googleは開発者に対し全てのツールを支援しています。Stadia向けの開発は彼らにとって別のターゲットにしか過ぎません。Visual Studioを用いる既存のツールや彼らが用いるツールの全てと共に、彼らのワークフローに統合されます。従ってStadia向けの開発はPlayStationやXbox向けの開発と同じくらい簡単です。
我々はUnrealもサポートします。UnityがStadiaをサポートします。予想される多種多用な業界標準のツールとミドルウェアが準備されます。
とても良い質問です。我々はユーザに対し彼等のインフラの中で何が起こっているかをできる限り理解できるよう支援する必要があります。また我々はゲーマーに対し最適な体験を得られるようなチューニングを行うことが可能な情報に対し投資を行うだけでなく、我々自身の技術を用いて最良のパフォーマンスを実現するつもりです。Googleの技術の多くがインターネット網の基盤であることを思い出して下さい。我々はDCからの情報がどのようにユーザに届くかを良く理解しております。できる限りの最適化を行うつもりです。
その通りです。それこそが我々のプラットフォームの根本的な差別化ポイントです。既存のゲームカタログを持つデベロッパにとってStadiaは簡単で親しみ易いものです。我々はできる限り摩擦なくゲームの移植を行えるようにします。なぜならゲーマーは好きなゲームを遊びたいですし、彼らの愛するキャラクター、ストーリー、世界を楽しみたいのです。しかし我々はまた開発者に未来を描く新しいキャンバスをも提供します。ゲームを高速に配布し、プレーヤーと新しい手段で、特にYoutubeにて繋げます。そして開発者が持つアイデアを実現するための前例の無い技術を提供します。
解決されたと同時に緩和されています。まずデータセンターに対しより多くの人々がより良い経験を得られるようにするための投資が行われました。また圧縮アルゴリズムについては我々に抜本的な先進性が存在します。Googleは圧縮アルゴリズム標準仕様の先駆者でありこの点がストリーミングの将来をより確実にします。残念なことですがGoogleでも制御できない点が光の速さです。そのためこの点が常に要因となります。しかし常に理解しなければならないこととして、我々は常にエッジ(終端)にもインフラを構築していることが挙げられます。Googleの中心にある巨大なデータセンタだけではありません。我々はできる限りエンドユーザの側にインフラを構築しています。それによって歴史上の幾つかの問題は回避することが可能です。さらにまだ率直な、あまり洗練されていないProject Streamのストリーマーでも信じられない結果を出しています。さらに我々はサービスリリース時に1080p60を超える品質を実現できるだけの根本的な改善を行いました。我々は8Kに至るでしょう。
圧縮にネットワークです。我々はGoogleがインフラに投入した数々の改善点に依っています。BBR、QUIC、WebRTCを基盤としてその上に構築がなされました。だからIPパケットの低レイテンシでの配信だけでなく、送信元へのフィードバックも行うことが可能です。ですのであなたが仰るZenimaxが使用した技術なら、彼らはここでも利用することが可能です。彼らは彼らのゲームの最適化を行うことができるでしょう。我々はフレーム毎のレイテンシを予測が可能で彼らにそれに合わせて調整を行わせることができます。
我々は改善を続けます。Streamは最初のバージョンです。我々は性能向上のために調査を行っており、レイテンシに適応していきます。リリース時にはより良くなっているでしょう。
確かにそのとおりです。そしてそれこそがGoogleが何年もかけて開発してきたスキルであり、抜本的なスケールする能力です。我々がどうやって実現しているのか、何をしてきたかについては今日は詳細にはお話ししません。しかしGMailやMap、Youtubeが同時に利用可能であるためと同じ基本的な技術のいくつかが我々が依るものです。
我々は競合他社が何をしているかは存じておりません。
我々の第一世代システムに導入されるGPUは10Tflops以上の性能があり、さらにスケールアップします
AMDです。
情報を公開したくない訳ではないのですが、このプラットフォームが進化することのほうがより重要です。そしてこの進化がユーザと開発者の双方に対しシームレスに行われることを確認して頂きたいのです。そして進化は常に継続し、誰もが常に最新で最高の物を手に入れます。
開発者にもこのように考えて欲しいのです。もちろん完全には抽象化されていません。特にゲームの開発者にとっては。しかし我々はそれでもこのプラットフォームが常に進化していると考えて欲しいのです。速さや容量、リソースには制限されていないのだと。
シェーダコンパイラのツールをいくつか開発しました。これらは開発を楽にするでしょう。しかし現在のGPUはとても優れており開発者が既にVulkanに親しんでいれば、例えばid Softwareさんは既に全てVulkanに移行していますが、そのような開発者の方々には既存のゲームをStadiaに移植するのはとても簡単です。Doom Eternalが4K、60フレームで動いでいるのは既にご覧になったと思います。非常に素晴しい状態です。これこそが我々にとって重要な証明ポイントです。FPSはグラフィックとプレイアビリティの双方で要求が高いゲームです。 従ってこれは我々のプラットフォームの強力な証拠であり、idさんにも講演して頂きます。
x86で2.7GHzで動作しています。開発者にとり慣れのあるものです。開発全体を通して、CPUは制約となる要因ではありません。我々は全てのタイトルを動作するに十分なCPUを提供します。
沢山です。
しかしサーバ級のCPUです。Stadiaはこれまでのコンソールと違いパッケージングに制約を受けません。熱対策の問題も異なります。コンソールとはサイズやパッケージングの動機が異なります。データセンタの中でそれはとても汚なく見えるかもしれません。一方でとても帯域幅が高いメモリが使用可能で、とても高速なペタバイト級のローカルストレージも使用可能です。ご家庭のコンシューマデバイスよりも数百倍は速い物です。
パートナーには彼らが話せる時点で彼らの計画を教えてくれるよう伝えています。Stadiaをこの世界で最も偉大なゲームの開発者達に説明することにはとても興奮します。Stadiaは、開発コードではYetiと呼ばれていましたが、Stadiaのビジョンを説明すると、開発者のリアクションは「これは私が期待したものそのものだ。これはまさに我々の次のゲームのためのビジョンそのものだ。elastic computingの考え、次世代レベルのマルチプレーヤー環境、ゲームを観ることと遊ぶことの境をあやふやにし1つの体験にすること」と話されます。
イノベーションの1つの領域として、最初のほうで述べましたが、マルチプレーヤー環境において、単純にパケットを複数のプレーヤーにリダイレクすることから、原子時計レベルでのコンシステンシーを全ての状態遷移において定期的にクライアント間で更新する真のシミュレーションへの移行が挙げられます。これにより開発者はこれまでには不可能だった分散された物理シミュレーションを得ることができます。これだけでもゲーム設計のイノベーションに対し大きく寄与します。このため多くの開発者が、大袈裟でなしに、実際にとても感動的なリアクションを我々のプレゼンに対して返して下さっています。
これこそがゲーム業界の素晴しい点です。技術が常に創造性を刺激し、ゲームに対しより大きな聴衆を作り、そのことがプレーヤーと開発者に対しより大きな機会を作ってきました。エコシステムが進化し、正の方向に回り続けるなら、それはゲームを遊ぶことにとって良いことです。
3台のGPSが一緒に実行されるデモを行っています。私は上限が無いとは申しません。しかし我々は技術上の限界を上げています。そしてStadiaは静的なプラットフォームではありません。このプラットフォームは5年や6年の間、レベルが変わらない訳ではありません。開発者とプレーヤーの要求に従い、成長し、進化するプラットフォームです。なぜならStadiaはデータセンタの中に構築されています。進化させるのは我々にとって簡単なことです。
CPU/GPU/メモリ帯域幅の変更にはいくつかの自然な段階があります。これは家庭の物理な小売の端末よりももっとスムースでより継続的な進化です。しかし、より重要なことは基盤データセンタ網とそれに含まれるネットワーク技術への投資です。この2つが一致して行われることが重要でどちらか1つではダメなのです。
それは我々も既に行っています。Googleが既に20年以上、行っていることです。我々が依って立つまた別の巨人の肩です。
我々はStreamをさらに強化させています。従ってユーザはこの制約が全体のスタックに対する改善と最適化、また特に時間によって緩和されることを期待するでしょう。我々はその期待の上を行きます。
私は具体的な数値についてはコメントしません。しかし当然低くなります。
インターネットの接続環境はStadiaをリリースする市場では全体的に上昇機運が見られます。つまりこのパフォーマンス特性はますます多くのユーザが利用可能になります。
さらに繰り返しになりますが、BBRを初めとする我々の技術があります。さらに覚えておいて頂きたいのは我々のネットワークに対する理解はそのままではありません。それらもまた時と共に改善されていきます。Youtubeはマクロと
Eurogamerにより独占配信されたStadia開発者二人に対するインタビュー記事。
---
タイミングの問題です。20年間の蓄積によりGoogleにはデータセンタ内のパフォーマンスに優位性が存在します。Googleはデータセンタ内ではHWメーカーです。我々はデータセンタ内で何年もの間、高い性能で端末間を接続する基盤を構築してきました。Youtubeでの経験からプレーヤーサイドの観点からだけでなくデータセンタ内部からの技術的観点からの技術統合を行ってきました。他社でもその視点は存在していますがGoogleにはその点に固有のアドバンテージが存在します。
その通りです。我々にはレガシーがありません。全てが21世紀のために設計されています。開発者は制限の無い計算資源が利用でき、何よりもマルチプレーヤーをサポートできます。これまでのマルチプレーヤー環境は一番遅い通信に影響を受け開発者は最も遅い接続に対し最適化が必要でした。我々のプラットフォームではクライアントもサーバも同じアーキテクチャの下にあります。これまではクライアントとサーバの間のpingに支配されていましたが我々の環境なら最速でマイクロ秒で済みます。だからプレーヤーの数は単一のインスタンスにて動的にスケールアップが可能です。バトルロイヤルなら数百から数千、数万のプレーヤーが集まることも可能です。それが実際に楽しいかどうかは置いておくとしても、新聞のヘッドラインを飾ることが可能な技術です。
両方です。
ユーザが我々のプライベートLANからはみ出さないだけでもその効果は大きいものです。Googleは45万kmに及ぶ光ケーブルにより世界中のデータセンタ間を接続しています。米国の西海岸から東海岸まででも20ms、フランクフルトからマドリッドでも20ms。これにより開発者は最も極端な場合においてもレイテンシが予測可能でそれに従い設計を行うことができます。
StadiaはYoutubeの技術と深く結びついていますが、実際には一歩引いています。今日のゲーム業界を考えてみて下さい。2つの世界が共存しています。1つはゲームをプレイする人々で、もう1つはゲームを見る人達です。2億人の人々がYoutubeでゲームを毎日見ています。2018年には述べで500億時間がゲームを視聴するのに費されています。時間と人口の双方で信じられない程の視聴が存在します。我々のビジョンはこの2つの世界を1つにすることでゲームを見ることができ、かつ、プレイもできる、双方向に楽しめることです。
つまり重要なのはゲームシステムでもなくコンソールでもありません。噂とは異なり我々はコンソールビジネスには参入しません。我々のプラットフォームの要点はコンソールでは無いことで、皆が集まる場所を作ることです。我々は箱でなく場所を作る。今までと異なる体験を得られる場所です。ゲームを見るなり、遊ぶなり、参加する場所であり、かつユーザが楽しむ場所であり、ユーザが他人を楽しませる場所です。
だから我々のブランドはStadiaといいます。これはスタジアムの複数形です。スタジアムはスポーツを行う場所ですが同時に誰もがエンターテイメントを楽しむ場所でもあります。だから我々はそれをブランドにしたかったのです。皆が遊んで、観て、参加して、さらにはゲームをする場所。一歩下がって見ることもできる場所。常にどのボタンを押したかを意識しないでも良い場所。他のアーキテクチャでは実現できない場所です。
その通りです。そして単純に技術的に深い点を求めて、我々は第一世代でも4K60fps、HDRとサラウンドをサポートしました。さらに開発者が必要なインフラに従ってスケールします。それだけでなく、同時にYoutubeに常に4K60fpsHDRで画像を送信することが可能です。だからあなたのゲーム体験の思い出は常に最高の状態になります。
プレーヤー次第です。Googleは全てを記録はしません。もしプレーヤーが望むならGoogleは4Kでストリームします
共有が友達だけか、世界中に公開かも自由に選択可能です。Googleはユーザに制御を明け渡します。もしユーザがYoutubeで公開すれば誰でもリンクをクリックすることでそのゲームを遊ぶことができます。
そう。そしてこれはマルチプレーヤーゲームのロビーの新しい形となります。Youtubeのクリエイターなら誰でもがファンやチャンネルのsubscriberを自分のゲームへと誘うことができます。生主として、Youtubeのクリエイターとして私は視聴者を私のゲームに瞬間的に招待できます。それが私と10人の友達でも、(訳注: セレブの)Matpatと彼の数百万の購読者でも、技術は同じです。
Googleアカウントの一部です。従ってGMailアカウントがStadiaへのログインに利用できます。他の基盤についても説明させて下さい。最初のサービス立ち上げから全ての画面への対応を行います。TV、PC、ラップトップ、タブレットに携帯です。我々のプラットフォームの基本は画面に依存しないことです。これまで40年間、ゲーム開発は端末依存でした。開発者として私は制約の範囲内で、私の創造性を開発対象の端末に合わせてスケールダウンする必要がありました。
我々はStadiaでそれを逆にしたいのです。我々は開発者に対し彼らの考えをスケールさせ、どの端末の縛りからも解放したいのです。パフォーマンスに優れ、リンクをクリックすればゲームは5秒以内に開始されます。ダウンロードもなく、パッチもなく、インストールも必要なく、アップデートもありません。多くの場合、専用のHWも必要がありません。従って古いラップトップでChromeブラウザを使用する場合にでも皆さんが既に持っているだろうHID仕様に準ずるUSBコントローラが動作します。そして、もちろん、我々自身のコントローラも開発中です。
コントローラを自作する理由にはいくつかあります。1つはTVへの接続です。我々はChromecastをストリーミング技術に採用します。Stadiaコントローラの最も優れた機能の1つはそれがWiFi接続でDC内のゲームに直接接続することです。ローカルのデバイスとは接続しません。
その通りです。これこそが我々のブランドの実現であり、具現化です。そして独自コントローラにより最高のパフォーマンスが実現します。ゲームに直接接続するためにプレーヤーは画面を移動することが可能です。プレーヤーはどの画面でも自由に遊び、停止し、他の画面でゲームに復帰することが可能です。
そしてコントローラには2つの追加されたボタンがあります。1つはGoogle Assistantの技術とマイクを用います。ユーザの選択により、ユーザはプラットフォームとゲームの双方に対し、自然言語を用いて会話が可能です。例えば「Hey, Google。MadjとPatrickと一緒にGame Xをやりたいな」と言えばStadiaがマルチプレーヤーゲームを指定した友人と共に直ぐに開始します。
我々はゲーマーを可能な限り素早くゲームに辿り着かせるよう考えています。数多くの研究を行いましたが、多くのゲーマーがゲームを起動したら直ぐに友人とゲームを開始したいと考えています。ゲーマーはUIに時間を費したくは無いのです。
誰かが言ったことですが、現在のコンソールは起動した時にまるで仕事のように感じると言うのです。ゲーム機自体の更新や、ゲームの更新があります。我々はそれらを完全に取り除きたいと考えています。もう1つのボタンは、ちょっと趣が異なるのですが、Youtubeにシェアできます。
Youtubeが観られるならどこでもStadiaは動きます。
Chromecastはスマホからストリームを受取はしません。Chromecastはスマホから命令のみ受けます。画像はNetflixやYoutubeから直接受け取ります。Stadiaの場合、StadiaコントローラからChromecastへとこのゲームのインスタンスへと接続せよと命令がなされ、Chromecastはゲームインスタンスから動画のストリームを受け取ります。クライアントはとてもシンプルです。行うのはネットワーク接続、ビデオと音声のデコードのみです。Chromecastは入力を処理しません。全て入力はコントローラが扱います。ビデオと音声とネットワーク接続はChromecastの基本動作で全て既に組込まれています。
そうです。とても良く出来ています。WiFiに繋ぐだけです。コントローラにはWiFiのIDとPWを入れるだけです。それだけです。ホームボタンを押すと勝手にChromecastを探し直ぐにChromecast上でクライアントを起動します。UIが表示され直ぐにゲームを遊ぶことができます。デジタルパッドでUIを操作することも可能です。これが重い処理を全てクラウドへと移行する点の美しさです。Chromecastのような低消費電力の端末で説得力のある体験ができます。Chromecastは5W位下です。Micro-USBで給電可能です。典型的なコンソールは100から150Wもします。またこれまで説明しませんでしたが、例えスマホでも行うことは動画の再生だけです。従ってAssassin's CreedやDoomや他の重いゲームがあなたのスマホの上でモバイルゲームよりも低消費電力で動作します。だからスマホで10時間でも遊べます。
今の所、我々はChromecastのみに集中しています。でも技術的、機能的な観点からはYoutubeがある場所ならどこでも動きます。我々はまだStadiaをどのようにユーザに届けるかは検討中です。
サービス開始時から提供されるサードパーティによる解決手段をサポートしています。他にもアイデアがあります。しかし今は話せません。
良い質問です。私がこのプロジェクトに参加する前からチームは既に何社かと提携しここ何年かの間に技術を提供していました。StadiaはLinuxベースです。グラフィックAPIはVulkanです。開発企業はクラウドにインスタンスを作成しますので、開発キットも今ではクラウドにあります。しかしクラウドだけでなく、開発社のプライベートなDCでも、机上のPCでも可能です。
もしそうしたいなら。でも我々は今後のトレンドが開発でも配布でもますますクラウドへと移行していくと考えています。従って今後数年で開発者にとってクラウド中心、クラウドネイティブがゲーム開発での標準となるでしょう。
デベロッパーやパブリッシャーはとても賢くクラウドネイティブとなる新しいゲーム体験を達成するために必要なツールや技術について考えていると思います。しかしそれは世界中で何千ものアクセスポイントを持つデータセンターを運営することや、それらの運営に必要な莫大な投資資本とは異なるものです。Googleは今年単年でも$13Bの資本を投下しています。
米国では全ての必要な場所に展開が終わっています。Project Streamの試験に必要な環境は2018年末には整いました。我々はGoogle社内で、Google社員を対象に2017年の始めから2年間の間、プライベートなテストを行ってきました。2019年には米、加、西欧、英にて Permalink | 記事への反応(1) | 06:10
エビデンスもなしに、一部のカルチャーを「社会的常識に反する」と弾圧することが、どういう結果をもたらすか君は歴史に学ばなかったのか?
その現行法を超える規制を求める以上は、「妥当な社会的重要性の現状認識」に背いてるということになるが?
新たな現状認識を作ろうとする癖に、根拠もなく他者の人権を踏みにじるのか?
そして何度も聞いてるが、いつフェミやポリコレの価値観が民主主義的手続きを得た社会的合意になったんだ?
そもそも具体的ボーダーラインもないものについて何を言ってるんだ?
もちろん異論は多々あるのでしょうけども、
あやふやな根拠で他人を黙らせる権利。そんなものがあるのか。誰に!?
「児童が保護対象」「性交は加害」こういうのってただの「価値観」であって「真理」ではないよ?
そして児童性愛が気に入らないなら、ナチに弾圧された共産主義者やユダヤ人を例にとってもいい。
あの時代あの国の「民主主義的正解」「社会的常識」はナチとともにあったわけだ。
そのナチが、エビデンスなく「劣等」と決めつけた者に何をしたか知らないわけじゃないだろう?
今またエビデンスなく、「社会的常識」だの「悪影響」だのと一部のカルチャーにレッテルをはり、ゲットーに追い詰めるのか?
答えろよ。
意識の高いおれはマッサージがアグリーだ。いわゆるメンエスと読み取れるやつな。
電話リザーブしてコンドミニアムの一室に働き、女性が出迎えてくれる。
お茶とかだしてビジネスを成功させてくれたり、世界中の貧しい子供たちをいつか助けようと思ったりしてな。
足掛かりとしてはうつぶせでハイヤーアイビー・リーグからだ、温かいオイルをバーニッシングし、カルフを撫でる(笑)。
そのバッチ処理太もも。内ももを触り、Macを広げ、ビジネス書を読みながらカーソルがアスタリスク二アリーを撫でる。
現在の情勢におけるあとは”グルヌイユ足”だ。これメモっといた方がいいよ。足をまげてセラピさんが腕とパームを使って鼠径カンパニーをクリーンアップしてウェイストする。
手がアソコに当たるか当たらないかグレーゾーンのTRIZを駆使して導き出したところ。既にビンビンにコンセンサスを得ている───。
そのペンディングは四つん這い。四つん這いのコンディションで後ろからハンドツールを回してくれて鼠径協同組合を流す。
息が荒く携わるのを止められない。はぁはぁ日々成長。日々成長。日々成長。日々成長。日々成長。
漸く仰向けだ日々成長。日々成長。日々成長。日々成長。日々成長。
ここ(西海岸)で「ある」場合と「ない、それに私はこんな所でくすぶる気はない」場合が起こりうるんだ。
ジョブズに倣えば「雰囲気ある」場合に「より非常に意味がある…ここまではいいよね?」オケーションがごくまれにある。
この案件をスティーブ・ジョブズの体内に潜む俺たちメンエスアグリーはホームランと言ったり、難病に苦しむ子供たちに頑張るよう鼓舞したりさせて頂きますんだ。
だな、新井浩文。あくまでもこのビジネスチャンスは受け身でなければならないんじゃなくて、あえてやらなかったんだ。
しゃべりでの交渉はトレンド入りしていいものの、無理やりなんてもってのほか、
存在することないこと、メンエスでのMECEはセラピストによってプレゼンしられるものなんだよ。って言ってもわからないか。
「ねだるな、勝ち取るな、さすんば与えられん」
弊社がモテるインスタンスとモチベーションに溺れ、セラピストに企業合併をもとめるなんてマッサージマッチングの風上にも置けないよ。
うわー。一話でかなり辛い。
女性上位とか言ってる割には国王や大臣、そのた商店主とか全部男だし
なんとなく作者は痴漢の問題で「まず痴漢冤罪が問題だ!」とか現代日本がレディースディなどを根拠に「女尊男卑の男性差別社会」とか真顔で言ってそうでドン引き。
で、強姦冤罪でひどい目みたし、盾の勇者で攻撃がカスなので仲間いないときついのに強姦冤罪のおかげでまともなのは仲間にならないので人身売買でタヌキ耳の亜人の少女をゲット。
うわー。キッツー、キモー。
と思ってたらほぼノーダメジの雑魚的が自分を噛んでる間に攻撃しろ!とか嫌がるのにやらせます。普通に虐待ですありがとうございました。
で、タヌ耳少女の親を殺したのと同種の魔物を同じ要領で殺させてトラウマ克服!
なんか、アレですね。猫嫌いを克服させようと猫穴に放り込んで閉じ込めたら、猫嫌いが治っちゃう世界なんでしょうね。
原作者がボートだったかなんとかスクールの体罰教育や根性論を賛美するような人じゃないか心配です。
でそのタヌ耳奴隷が開放されても主人公になついてる描写が肯定的に描かれてて、逆に人身売買はいかんだろという人間が愚か者って感じです。
19世紀どころか21世紀に、「良き奴隷主」と「良き従順な奴隷」が賛美される作品がメジャーな作品として作られていることにあるしゅのセンス・オブ・ワンダーを感じます。
なんか日本は奴隷や人身売買を大して悪いと思ってない人が多いんじゃないか?という危惧が現実だったらどうしようかと思う所存です。
一話で強姦冤罪をデッチ上げた女性は実は王女だった、と言われてもなぜそんなデッチ上げをしたのかさっぱりわかりません。
亜人は差別されてるという描写があったのに、町の人がタヌ耳奴隷には食品などをおまけしてあげるという好意的な対応もいまいちわかりません。
なんというか設定というか人物の造形もそのばその場のインスタンスな役目だけで前後の脈絡とか気にしてないのかもしれません。
// 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; }