「オブジェクト指向の倒し方、知らないでしょ? オレはもう知ってますよ」

「オブジェクト指向の倒し方、知らないでしょ? オレはもう知ってますよ」

オブジェクト指向と公的教義の倒し方を知っているブログ
荀子を知っているブログ 織田信長を知っているブログ

近世日本の身分制社会 は 2025/09/29 168 で終了。

誤認の修正以外は現段階ではしない前提。後で一斉に全体を見直し、分量を集約したいが未定。

2025/11/24 から次議題 Windows プログラム C/C++ ( オブジェクト指向の規律絶対主義への否定 )開始。

01章 2025/11/24 : 02章 2025/11/27 : 03章 2025/12/04

04章 01/03 2025/12/13 05章 01/03 2026/02/28
04章 02/03 2025/12/30 05章 02/03 2026/03/20
04章 03/03 2026/01/12 05章 03/03 2026/04/01

06章 01/02 2026/05/17 07章 01/02 2026/08/09
06章 02/02 2026/06/08 07章 02/02 2026/08/31

Windows  C/C++ DIB 検証報告プロジェクト GraphicBuild と PackBmp 02/02 2026/08/31

 

※ ここでは Windows 10 / 11 のPCを前提としていること、無料公開されている Microsoft Visual Studio Community 2026 がインストールされていて当アップロードファイルのプログラムソースファイルを確認できる前提、統合前 32 Bit 時代の Windows 標準 API 中心( 原点回帰中心 )を前提に、何に対する向き合い方でも同じことがいえる次の段階 自分たちにとっての上同士視点といえる、何にでもいえる年期計画的な目的構築・組織構想に向けての異環境間領域敷居管理・式目序列規律更新観 = 自分たちがしなければならない自分たちにとっての上同士視点の前回分・今回分・次回分以降の境界・段階・階層管理の選任評議交流規律といえる年々の上方修正の原本作りの問い合い )においてやってしまいがち・陥りがちなあるある話の教訓を議題の中心としている。

 

※ よそのこと道義領域外のことがどうであれの、まず自分たちの前提( 上同士視点の上方修正といえる社訓的な近代選任評議会的規律 = 本来の国際人道観 )がそもそもどうなっているのか、まずその等族義務の果たし合い( 異環境分野間の論述整理観・議事録処理観 = 自分たちにとっての上同士視点の年々の式目敷居規律更新 ができたことがない、目先の利害次第に何もかもをうやむやにし合う下の作り合いに全意識を全力で向け合うことしか能がない教育機関絶対どもおよびオブジェクト指向の規律絶対どものような無神経・無関心・無計画な上同士失格の怠慢の顔色のたらい回し合い・厳しさの向け合いは、ここでは次世代交流規律( まずは上同士視点の上方修正原本からのきざみ下方修正・年期計画の基本中の基本を重視し合うことができているのかの問い合い = 荀子・韓非子・孫子の兵法が喚起している目的構築論・組織構想論の手本の問い合い 荒らしの法賊行為・老害愚行と見なし、上から順番の厳しさ上乗せ倍増論で踏みにじって当然が前提になっている。

 

 

今回は、前回07章01で案内した GraphicBuild プロジェクトと PackBmp プロジェクトのふたつの、これまで通りの調子のプログラム側の紹介をする。

 

前回ページ07章01を確認している前提、05章 AssisKeep プロジェクトまでの当ブログの様子をざっと見ている前提で、紹介を進めていく。

 

これまで説明してきたこととして、次の段階の上達にはデータ設計優先( = その重要事項のひとつが動的性と静的性の概念間整理 )がまずは重要ということで、GraphicBuild の BMP データ管理の手助けを目的としている PackBmp の方から紹介していく。

 

まず PackBmp については 、04章 WindowBuild、05章 AssistKeep の系譜の拡張版であるため、その流れをざっと見渡しているなら、今回の構築自体は大して難しい訳でもない。

 

画面情報の PackBmp01.txt で

 

 

 

 

7項目の役割番号によって

 

 

 

 

PackBmp プログラム側のまず定数の概念整理から各処理を追加していくやり方は、以前通りになる。

 

今回 PackBmp からは、今まで無かった BMP 画像を表示させるための STATIC 部品 206 番の SV 概念を新たに追加することになったが、前回 AssistKeep から今回 PackBmp にかけての改善余地に対する改良も順述していく。

 

ただし PackBmp はあまり汎用的な目的ではない、GraphicBuild 側の FPS / DIB 設計の補佐のための限定一例的な目的が強いことと、今回分の拡張部ひとつひとつは WindowBuild / AssistKeep の延長線の単調なものか多い理由から、操作面の簡潔な説明と、今回分の改善余地の改良の簡潔な説明に留( とど )めることにする。

 

 

< PackBmp プロジェクトの exe 実行の画面 >

 

 

 

 

赤 1  BMP ファイルの対象フォルダパス

赤 2  フォルダパス選択呼出し

赤 3  リスト選択中の BMP 表示

赤 4  リスト選択中の BMP のサイズ

赤 5  リスト選択中の 役割番号・設定値1・設定値2 の入力および設定変更

 

赤 6  上位桁と下位桁( 各 2 ~ 4 まで )の入力および桁変更

赤 7  リスト選択中の上位枠の値に対する変更操作

     ① 次枠入替 選択中の上位枠と次の上位枠との総入れ替え

     ② 上位+1/-1 リスト選択中の上位値を+1/-1

     ③ 以降+1/-1 リスト選択中以降の各上位枠の値を+1/-1

赤 8  リスト選択中の下位に対する、上位枠内変更操作

     ① 入替▲/▼ その上位枠内での下位の上下の入れ替え移動

     ② 下位+1/-1 リスト選択中の下位値を+1/-1

     ③ 以降+1/-1 その上位枠内の、リスト選択中の下位以降の値を+1/-1

 

 ※ 赤6~8 は即実行のファイル名変更

 

赤 9  付与情報操作( 役割番号・設定値1・設定値2 )

     ① 挿入    上位枠は無関係にリスト選択行の付与情報に 0、0、0 を追加して下行にシフト

     ② 削除    上位枠は無関係にリスト選択行の付与情報を削除、下行以降をリスト選択行に詰める

     ③ 入替▲/▼ 上位枠は無関係にリスト選択行の付与情報を、前の/次の行と交換する

 

赤10  作成処理

     ① 生成:情報 出力名で付与情報の txt 一覧を作成する

     ② 生成:Pack 出力名で付与情報の txt 一覧と pkb ファイル( BMP 1ファイル化 )を作成する

 

※ pbk フォーマットは単純

 

     ① 4 バイト BMP 件数

     ② 4 バイト x BMP件数の、各 BMP のバイト開始位置(検索用)

     ③ 以下、Width 4 バイト、Height 4 バイト、( BMP 各 BITMAPHEADER 計 54 バイト分は除外 ) BMP データバイトx件数分

 

 の順に書き込まれる。① と ② はヘッダー的情報で、対象 BMP ファイルが 50 個だった場合だと 4 + ( 4 x 50 ) = 204 BYTE 分が ① と ② になり、以降、BMP ヘッダー 54 バイトは除いた Width 4 バイト Height 4 バイトの計 8 バイト + BMP データ分が一覧順に書き込まれる仕組み。

 

読み込み側の GraphicBuild では最初に BMP 全件分を読み込む前提になっているため ② は不要だったが一応付与。PackBmp で BMP を書き込む際も、GraphicBuild で pkb から BMP を読み込む際も、Width が 8 ( 厳密には 4 )で割り切れない場合の横1ラインあたりのパティングバイト計算をしながら BMP データを書き込む/読み込む作りになっている。

 

 ※ txt 出力の方はリストの一覧の状態がそのまま書き出される。

 

赤11  リスト再表示

 

赤12  リスト

     No  GraphicBuild 側の ViewBmp 構造体配列の実際の配列番号

     BMP GraphicBuild 側のファイル番号検索用

     役割 4バイト付与情報1個目 役割番号

     設1 4バイト付与情報2個目 設定値1。Left の初期値で使う場合有り

     設2 4バイト付与情報3個目 設定値2。Top の初期値で使う場合有り

 

 ※ 役割、設1、設2は出力名.txt ファイルから参照するが、No と BMP ファイル番号名については txt からの参照はせず bmp フォルダの状況から毎度作り直す。BMP の実際の件数と txt の件数が一致しない場合、txt 側が足りない分は0、0、0で埋め、txt 側の方が多い場合は切り捨て扱いで一覧作成する。

 

 ※ PackBmp の性質的な仕様として BMP ファイルは数値のみのファイル名を対象とし、リスト作成時の認識の仕方として上位桁の開始は 1 ~ 9 までの1桁であることを条件とし、ファイル名の左から最初に見つけたその値を基点に上位桁数と下位桁数が2~4桁かどうかを自動認識する仕組み。

 

 

< 04章 WindowBuild 系譜 05章 AssistKeep から 07章 PackBmp にかけての改善余地に対する改良 >

 

改善1 : 画面構成の役割番号の定数名の改良。3回目の企画ということで前回 AssistKeep までと意義が被るものが増えたことで解りにくくならないよう、画面企画ごとで定数名を解りやすく変更( 上述の定数の所とで対応 

 

※ 変更前( AssistKeep  時点 )

 

 

 

 

以下変更後。WindowBuild は WB、AssistKeep は AK、PackBmp は PB を入れることで画面の企画ごとで区別。

 

 

 

 

改善2 : AssistKeep プロジェクトで共用手続き CheckWndStr が追加され、これで部品名の判定ができるようになったため、それまでの Tab キー処理等で EDIT か LIST か BUTTON かを GetClassNameW( Windows 標準 API  )で判定していた旧箇所は、PackBmp からは全て CheckWndStr で一本化。

 

まず CheckWndStr 手続き関連の定数を追加。

 

 

 

 

CheckWndStr 手続きでの追加対応。

 

 

 

 

Tab キー例での対応( 他は省略 )

 

 

 

 

EDIT か LIST か BUTTON かを、部品クラス名の頭文字で判定していた以前を PackBmp からは CheckWndStr 手続きによる true / false 判定の仕方で統一。

 

改善3 : EDIT と LIST を連動させる意義のプロジェクト共用手続き UnionEventPathList は WndProc( GetMessage )の契機が主となるため手続き名 EventUnionPath に変更。画像は省略。

 

改善4 : プロジェクト名 Env.txt( 環境ファイル ) に1項目追加( 出力名 )することになったついでに、このファイルが存在しない場合はデフォルト環境ファイルが自動生成される作りに改良。画像は省略。

 

改善5 : EDIT 部品 / LIST 部品 / BUTTON 部品に対する取得および指定において、これまでHWND の配列番号でやりとりしていた場合と、HWND のハンドル値でやりとりしていた場合とで混同していて一貫性がなかったため、可能な所は後者で統一。

 

 

 

 

一例( 修正箇所多数 

 

 

 

 

Windows 標準 API の手続きでは、Windows 側から何らかの数値やハンドル番地などを取得しようとする際に、該当無しだったり無効だったりを知らせるために 0( nullptr )や -1 を返す仕組みになっているものが多いため、当ブログ筆者もその方式を参考にしているが、配列番地の概念による無効の -1 よりも、ハンドル番地の概念による無効の nullptr の概念で統一した方が概念整理的に何かとすっきりすることに気づいた( Windows 標準 API の手続きの多くは、引き数の番地指定に nullptr を始めとする前提外を送ったとしても無効扱いになるのみで大抵は強制エラー落ちにならない作りに配慮され、GetDC のように中には nullptr を渡すことがデフォルト指定の仕様になっているものもある。 一方で、C補佐の性質から内部処理が機械語感の強い作りのものも多い Windows CRT 側では nullptr も含めて前提外の値を指定すると強制エラー落ちになってしまうものも少なくないため注意が必要 )ため、可能な箇所は後者で統一することにした。

 

改善6 : メインウインドウハンドルかどうかを判定したり参照したりする際に、これまではメインウインドウハンドルが入っている g_hWnd[ 0 ] を参照していたが、概念名の弱い( 機械語感の強い )参照の仕方であったため、g_hWndMain という明示的なプロジェクト共通変数名( グローバル変数 )を設置し、その中にメインウインドウハンドル( g_hWnd[ 0 ]  )の値を入れておき、メインハンドルの認識の仕方はその明示的な変数による参照で統一。画像は省略。

 

改善7 : 数値を文字列化する際、指定桁数による桁数分の前方の 0 埋め処理をするために AssistKeep プロジェクトの時に共用手続き StrNumZero を用意したが、PackBmp では前方に0を埋めるだけではなく前方にスペースを埋めたい場合も出てきたため、StrNumZero は廃止し( 旧廃策の対象とし = 大した規模や仕様史でもない中で、概念名・式目名の意義・象形をいたずらにうやむやに薄めるような無関心・無神経・無計画なラッパー/オーバーライドの残存乱立は避けることにし )、前方に何を埋めるかの指定ができる StrNumForm 手続きを作ってそちらで統一。説明画像は省略。

 

改善8 : PackBmp からは、STATIC 部品に BMP を表示させる仕様を追加するようになった( 上述の画面説明の 赤3 の部分 )が、画面部品 STATIC 系の役割名 ST / SL / SB のパラメータではできないことが判明し、新たに SV を追加。( 上述の画面構成 PackBmp01.txt の7行目 

 

 

 

 

少しややこしいが、画面部品 SV ( WS_CHILD | SS_BITMAP )に対する BMP 表示処理の紹介も簡単にしておく。

 

 

 

 

リスト側のリスト選択に変更があった場合の処理は EventUnionPathList 手続きで行い、まず 赤1 が SV の役割番号 206 があるかどうかの判定、 赤2 で BMP 読み込みを行い、 赤3 で SV 部品に BMP 情報をメモリ転送するためのコンテキスト準備、 赤4 で画像の大きさによって縮小表示する場合の計算を行い、 赤5 で SV 部品に BMP 情報を結び付ける処理、 赤6 でメモリの残骸負荷を残さないための不要情報の撤去、という手順になる。


ついでに 赤7 の所は、役割番号 207 ( 文字列表記部品 )があれば、その BMP のサイズ値( Width と Height )を文字列化して表示、になる。

 

赤3 で、GetDC( Windows API )で取得した色情報を元に、BMP データを転送するための転送のコンテキストハンドルと転送のコンテキストハンドルの準備をしているが( Windows API の CreateCompatibleDC )、GetDC での nullptr 指定は恐らく GetWindowDC の 0x10010 指定( デスクトップ画面指定 )あたりを意味、つまり Windows の画面設定の大きさ、Bit 色、リフレッシュレート等といったOS設定の情報を取得するためのものになる。

 

CreateCompatibleDC( Windows 標準 API ) で互換コンテキストハンドルをただ生成するだけなら nullptr 指定でも良いが、その指定で作ると、24 Bit 色として扱いたいという基本情報の確定ができず BMP データの転送処理( Windows 標準 API の BitBlt 手続きや StrecthBlt 手続き等 )が無効になってしまうため、BITMAP データ型関係を用いて 24 Bit 色情報だとそのコンテキストハンドルに設定しなければならない手間を、この手順ならその 24 Bit 色指定の手間を省いたコンテキストハンドルが生成できる、という意味になる。

 

統合期 32 Bit Windows XP ( 2003年~2009年くらい )時代あたりまでは、2017年以降製あたりのPCと比べるとだが廉価PCは低速なものも多かった( 性能が高くないCPUでグラフィックボード非搭載の場合、チップセット代替描画処理が必要な分、CPUとメモリに結構な負荷がかかってしまう )ため、使用するPCと使用するソフトウェアの都合によっては Windows の画面設定を 24 Bit 色から 16 Bit 色に落としてやらないとソフトウェアの動作条件と処理速度に支障になる考慮が必要な時代だったが、64 Bit の浸透期となる Windows 7 搭載PCあたりからは 24 Bit 色設定を 16 Bit 色設定に落とす必要もいい加減になくなってきているため、近年の Window 10 / 11 PCでは( 24 Bit 色を前提とする場合は )GetDC を用いたこの方式( BMP 用コンテキストに対する 24 Bit 色設定の手順 )でほぼ問題ない。

 

STATIC 部品にただ BMP 表示をするだけ( BMP データをその画面部品の画像描画コンテキストにただ結びつけるだけ )の簡単そうな話でも、統合前 32 Bit 時代以来の Windows 標準 API の根底概念からだとこのように、どうしても少し煩雑な手順を踏まなければならないこともあるが、逆にいうと Windows の元々の仕様がなぜそう細分化されているのかを窺い知る良い機会ともいえるため、ここだけ簡単に紹介しておくことにした。

 

PackBmp では AssistKeep 分までの改善余地について、上述の他にもいくつか改良を施しているが他は省略する。

 

今回 PackBmp プロジェクトの場合は、前回系譜の AssistKeep プロジェクトのように Microsoft Edge の補佐( 他インスタンスウインドウ間での動作の補佐 )を目的とした分だけその事情も少しややこしかったのとは違い、PackBmp の場合は同インスタンス内中心でひとつひとつは単調、汎用性において AssistKeep よりも目的もだいぶ限定的であるため、詳細は省略とし PackBmp の説明は以上とする。


 

< GraphicBuild >

 

GraphicBuild の説明に入るが、今回紹介することになった GraphicBuild プロジェクトは前回 GraphicBuildTrial を紹介することになった段階の時と同じく、この段階で改善余地だらけであることも含める紹介となることを、健全な意味であらかじめ断っておく。

 

前回 GraphicBuildTrial の時と同じく、ここからさらなる概念間整理を一気に進め過ぎてしまうと、説明を作る側としても読み手側の理解としても難易度がだいぶ上がってしまいそうなことと、報告までの時間も長期化してしまいそうだったこともあり、今回はあえてこの状態で紹介することにした。

 

むしろこの段階での中間的な報告にしておくことで、その方が上同士視点のあるある的な前回分・今回分・次回分以降の基本的な向き合いの伝え方ができる機会と位置付けることにし、そこも含めて順述していく。

 

まず、メインソース( GraphicBuild.cpp )開始部の前方手続き群の概要から触れ、どのような構造なのかの説明に進めていく。

 

 

 

 

まず、前章06 GraphicBuildTrial 02/02で明記しておいたこととして、C++( C拡張だと謳っているオブジェクト指向 ) の特徴である構造体手続きは用いない前提は、今回 GraphicBuild でも同じになる。

 

前回 GraphicBuildTrial では ViewBmp 構造体と ViewTask 構造体のみだった状態から今回 GraphicBuild からは ViewText、ViewNature、MouseTask の構造体概念が追加され、それら概念名・式目名ごとの概要をまずざっと説明する。

 

ViewBmp 系概念  BMP データひとつひとつの格納およびその初期値的管理。今回例の BMP 個数によるこの配列数は51個。

ViewTask 系概念  今回例では表示枠単位および各 FPS の管理。背景表示( 1個 )、自然3種背景表示( 3個 )、前景2位置表示( 人物画2個 )、自然3種前景表示( 3個 )、レイアウト関連および DIB 化文字列表示枠( ボタンや文字列表記などのレイアウト部品的な各配置の合計。今回例だと12個 )、という管理単位。今回例のこの配列総計は 1+3+2+3+12の計21個。

 

レイアウト関連の今回例の12個の数え方。

 

 

 

 

ViewNature 概念 ViewTask が自然3種が目的だった場合のその担当概念。今回例だと背景3個+前景3個でこの配列数6個。

ViewText 概念  ViewTask が DIB 化文字列表示が目的だった場合のその担当概念。今回例でのこの配列数2個。

MouseTask 概念 ViewTask がマウス操作を対象としている場合のその担当概念。今回例では < と > の2個のボタン、自然切替3個のボタン、人物切り替え4個のボタン 2+3+4 でこの配列数9個。

 

手続きの前方宣言群の所で 赤A と指摘している部分は、Alloc という概念名が入っていれば配列全体を対象としている手続き、入っていなければ配列単体を対象する手続き、という意味付けにしている。

 

当ブログの初動となる オブジェクト指向の倒し方01~11 の方で指摘していることとして、改善余地だらけのまま性善説放任主義を30年以上たらい回し合い続けてきたC++( オブジェクト指向 )は、C拡張( 次の段階への具体化をごまかし続けてきたパラダイムとやら )を謳っておきながら、配列に対する単体参照と全体参照の概念間整理を手助けする機能の追加もしていなければ、その等族指導の果たし合い( 自分たちの上同士視点の上方修正といえる再細分化と再集約化の手本の作り合い も一切してきていない、その時点で動的性と静的性の概念間整理などなおできる訳がない、すなわち目先の利害次第ごとの片手間感覚で今いい所取りした無関心・無神経・無計画な弊害規律を作り合う( アルゴリズム設計側・出力設計側の旧態不都合をデータ設計側・次の段階の入力設計側に押し付け続ける )ことしか能がない教育機関絶対とそのただのいいなりの知能障害どもの姿そのものといってよい。

 

※ 当ブログの初動 オブジェクト指向の倒し方01~11 記事の方で指摘しているが、今一度、配列単体への参照概念 と 配列全体への参照概念を説明しておく。ここはC原点回帰側である Windows 標準 API の仕様史( Microsoft 公式の旧 MSDN から現 Microsoft Learn まで )から見渡せばはっきりしていることとして、そもそもデータ設計優先の基本中の基本の認識もできていないC++( オブジェクト指向 )の構造体手続き( クラス関数 )の仕様は、配列単体の場合と配列全体の場合の参照を快適に概念間整理させる機能など一切追加せずに無関心・無神経・無計画に絶対規律を乱立している時点で致命的な欠陥といってよい。C時代のそうした階層参照のわずらわしさの課題的検証への改善余地に対し、C++側はその改良努力など何ひとつしていないことからだけでもはっきりしていることとして要するにC++は、Cの define を乱用しているだけの無関心・無神経・無計画すなわち低次元な偽善規律( これまでも説明してきたが、define はデータ設計優先の概念間整理と一切関係のない記述上の代替機能としてもいくらでも使えてしまうからこそ、面倒がる目先の便利さだけが動機になっているような安易な使い方は上達から遠のくから、安易に使ってはならないと当ブログで指摘。概念間整理・式目整備をしている気に錯覚し、正しさとやらを確定し始めてしまうことが致命的な手抜き設計をしてしまっている自分たちの見直しも自分たちでできなくさせ合う迷走の原因 )に等しい。データ設計優先( 次の段階の入力設計 )の基本を壊し合わせるアルゴリズム側( 出力設計 最優先の絶対規律ばかり追加し合うことが概念間整理の高度技術かのように偽善曲解し合うことしかしていないその姿こそ、教育機関絶対どもの愚かさだらしなさの姿そのものになる。C++( オブジェクト指向 に関する知能障害どものその供述( 書籍やネットでのオブジェクト指向の説明の仕方 を見渡せば容易に窺えるが、C原点回帰のデータ設計を完全無視させ合うオブジェクト指向の規律絶対をいきなり丸覚えさせ合うことに全意識を全力で向け合うことしかしていない態度丸出しからもはっきりしているように、すなわち上達( 次の段階 )において重要になってくるまずはデータ設計優先の概念間整理の基本中の基本など自分たちでできたことがない末期症状の姿がはっきり現れている。

 

× ( 目先の利害次第に片手間感覚で今いい所した無関心・無神経・無計画な上同士失格の怠慢の顔色を向け合い続け、手遅れ寸前と手遅れの狭間を迎えてから )お前に我々の何がわかるというんだ!

 

〇 そちらがどうであれ、とにかくウチとしてはこういう場合はこうした対応内/対応外の線引き的な規律体制( 準備要領 )になっている、というまずは自分たちの式目規律 境界観・階層観・段階観の概念間規律 を自分たちでうやむやに低次元化させ合わせない信用事故再発防止のための、年々のその確認のし合いの基本( 履歴管理ISO9000系の元々の動機。自分たちの上同士視点の上方修正的・年期更新的な選任評議序列統制 )を重視している。

 

※ × を押し通し合うことしか能がない、最初から最後まで何もかもうやむやな態度丸出しの教育機関絶対どもの分際 に過ぎないのか、それとも 〇 を重ねる等族義務の果たし合いの敷居交流規律を重視しようとしている高次元側 なのかをまずは見渡してみればよいだけの話になる。20代30代の小僧小娘ならともかく40代にもなってその最低限の問い合いも自分たちでろくにしてきていない、だからそこを問いただされる側の手のかかる上同士失格の分際の時点で釈迦に説法というだけの話に過ぎない。ここは Windows プログラムでも他でも共通。

 

FPS 概念と DIB 概念の掛け合わせである今回 GraphicBuild プロジェクトは、FPS 概念に慣れていない時点で少々ややこしい構造になりがちであることを前置きし、概要を説明していく。

 

まず、ViewBmp 概念の方はあくまで BMP 置き場( および、その初期設定値置き場 )で、表示状況、表示数、表示順などを司( つかさど )る中心が ViewTask 概念の方になる。

 

ViewBmp 関係の情報群は、最初に全 BMP とその付与情報を翻訳都合的に読み込んで以降は、ViewBmp 情報群には変更をかけることはしない参照元としての見方 この存在のことをマスターデータと呼ばれる場合も多い )に徹し、どの BMP をどの位置にどう表示するのかといった状態は ViewTask 側の情報群を手始めに管理、分業しているのが構造の特徴になる。

 

FPS 値の経過時間との連携も含める各表示単位の管理の中心が ViewTask 概念で、その ViewTask 単位の用件ごとで、DIB 文字列化表示を用件としているならその ViewTask 配列番目と ViewText とを結びつけ、自然表示( 雨、雪、桜 )を用件としているならその ViewTask 配列番名と ViewNature とを結びつけ、マウス操作を用件としているならその ViewTask 配列番目と MouseTask とを結びつける、という構造にしている。

 

今回 GraphicBuild プロジェクトでは、入力側( データ設計側 )はある程度は概念整理を進めているが、出力側( アルゴリズム設計側 )としての ViewText、ViewNature、MouseTask の概念整理が進められていない分、暫定の固定的な作りになってしまっている、ViewTask との結び付け方の概念間整理が途上のままだからその部分の作りが少しややこしく難読化してしまっているそこが次回分以降の改善余地になる。

 

今回では FPS 管理も含める表示管理の主体である ViewTask と、配列数的にはそれぞれバラバラな ViewText、ViewNature、MouseTask とを結び付ける概念整理が途上状態のままで、特に MouseTask 関連が各挙動の関係性が未整備の固定的な作りになってしまっている、だからそのアルゴリズム部分が仕様書性・可読性が低いままの暫定の作りになっているため現段階では見渡しにくくなっている。

 

< MouseTask が担当している主な挙動 >

 

 仕様1 マウス左クリック押下( おうか )の動作および + 押下対象にマウスカーソルが触れたらふちの点灯を通知

 仕様2 仕様1 + 押したら有効中/無効中に差し替え

 仕様3 ( 仕様1 ) + 仕様2 + 他の関連が有効中なら無効中にする

 

この挙動3種と、配列の関係性との概念間整理にだいぶ時間がかかりそうだったことで、そこが不十分な暫定的な作りになっているため、現段階では MouseTask 関連は見渡しにくくなっている。

 

※ 付与情報の 役割番号・設定1・設定2 からだけでも管理可能ではあるが、数字のみの管理は機械語観ばかり強まってしまう危惧もあったことで、今回は暫定的な作りのまま紹介することにした。PackBmp 側の画面構成の ST、EP、LI、BU  概念のように、付与情報に挙動記号項目をひとつ追加するといいかも知れない。いったん進めてみるから改めて見えてくることは常によくあることだからこそ、次の段階に向かうに連( つ )れ、常にいくらでも出てくる自分たちの改善余地に対する積極的な向き合い方、すなわち自分たちの上同士視点の上方修正的な前回分・今回分・次回分以降の履歴管理( 境界管理・階層管理・段階管理・傾向管理 )による順序立てを常に怠らない姿勢が、自分たちの次の段階への上達において重要。

 

現段階ではまだ今回分の概念整理は全く進めていないため、もし GraphicBuild 系譜で次の紹介をする場合は、この改善余地をどう検討・整理したのかの報告もする。


今回 GraphicBuild の構造をざっと説明するために、Windows プログラムの基本部である wWinMain 手続き内でどのような初期設定的な作りにしているのかの概要を説明する。

 

 

 

まず、赤線A上部 と 赤線B下部 については PackBmp 系譜とほとんど同じになる。

 

赤 1 プロジェクト共用手続き ViewBmpAllocInit によって、BMP データを固めた Graphic.pkb データとその付与情報 Graphic.txt を読み込み、基点的・マスターデータ的な配列構成をする。付与情報は ViewTask 他の初期設定に影響する。

 

赤 2 Windows 標準 API 手続き CreateFontW によって( DIB 化して文字列表示する予定の )フォントの基礎情報を用意。

 

赤 3 プロジェクト共用手続き ViewNatureAllocInit によって、今回例では自然6配列分を用意。

 

赤 4 背景画の個数管理のための変数設定と、最初に表示される背景番号を設定。

 

赤 5 表示箇所ごと担当 ViewTask の個数を設定。ややこしい数え方をしている部分が、BMP データ側からマウス操作部品に対する区切りを確認している改善余地の部分。

 

赤 6 プロジェクト共用手続き ViewTaskInit によって、各表示役割ごとの初期設定を行う。引き数の1個目が配列番号。赤5の方と比べるとだが、こちらの方がだいぶ仕様的・可読的な作りになっている。

 

赤 7 プロジェクト共用手続き MouseTaskInit によってマウス操作対象を判定管理するための配列を初期設定。

 

赤 8 DIB( 自由形 BMP 表示仕様 )1面分の領域を使用するために、Windows 標準 API 手続き CreateDIBSection で初期設定。ここでは CreateCompatibleDC に nullptr( 0 )を指定して色情報が未確定な HDC を生成しているが、CreateDIBSection の方で BITMAPINFO 構造体( Microsoft が用意している BMP 環境関係を扱う際の構造体 )から DIB1面分のサイズと色情報を指定した HBITMAP 情報を生成し、Windows 標準 API の SelectObject 手続きでその HDC と結びつける仕様になっているため。

 

赤 9 プロジェクト共用手続き StrMenu で DIB 化する予定の文字列を設定。

 

赤10 1秒間ごとの FPS を管理するための変数群を初期化し、Windows 標準 API 手続き SetTimer を使用して、FPS 進行計算用の WM_TIMER メッセージループを WndProc に発生させる。( 64 Bit コンパイルでは WM_TIMER は自動的に半マルチタスク化にだいぶ改善されている 

 

 

できるだけ1ページ内で説明を収めたい中でのブログ機能の字数制限の都合で、FPS 設計および DIB 設計に関する要所だけ説明していく。

 

DIB 設計の特徴が窺えるひとつが、プロジェクト共用手続き ViewTaskPos で

 

 

 

 

少しややこしい計算をしているが、ここでは概要図としては

 

 

 

前景の Left と Top による表示位置が、このようにメインウインドウの DIB 領域から外れる場合、背景に反映させる前景の開始位置と終了位置の走査線を、赤色の部分が示す開始位置と終了位置の走査線となるよう計算している部分になる。

 

以下が ViewBmp 構造体と ViewTask 構造体となるが、

 

 

 

 

 

 

ViewBmp 構造体の方では BMP の個数分の配列が作られ、各 BMP データおよびその付与情報を最初に翻訳的に読み込んだ後は、ViewBmp 構造体側の情報は変更しない前提( 一部例外有り )の、マスターデータ的な使い方にしている。

 

背景も含め、その場所にどのような目的でどの BMP を表示するのか、を FPS 都合と共に管理するのが ViewTask 構造体で、PackBmp 側で紹介した付与情報の、例えば人物表示については設定1と設定2の項目情報を左側人物と右側人物の初期位置( Left と Top の位置 )と扱いつつ、どの前景 BMP 画像をどこに表示するのかのその Left と Top の設定による、画像走査線の開始位置と終了位置は ViewTask 構造体側で管理、それが vt_iDibLeft、vt_iDibTop、vt_iBmpLeft、vt_iBmpTop、vt_iBmpWidth、vt_iBmpHeight 変数で、上述 ViewTaskPos 手続きはそれを算出するためのものになる。

 

データ設計優先の向き合い方としてこのように、この構造体/変数群ついては最初の翻訳的な初期化処理以降は書き換えはしない参照中心の静的性の強いデータ部 アルゴリズム側による変更の加え方ではなく、準備するデータの書き換えによる変更の加え方を基本としている考え )、この構造体/変数群は操作管理などのための変更がよくかかるのが特徴的な動的性の強いデータ部、といったように、各担当の傾向ごとに概念間整理を何度も見直していく姿勢が、次の段階の上達において重要になる。

 

 

< WndProc の WM_TIMER メッセージ >

 

上述 wWinMain 赤10の所の、Windows 標準 API SetTimer 手続きによって、WndProc( GetMessage )の WM_TIMER メッセージのループ的発行を設定しておくことにより、WndProc の方で

 

 

 

 

WM_TIMER メッセージが来た時の、FPS 進行の計算と、FPS ごと( ディスプレイのリフレッシュレートに合わせた 01/60 秒ごと =  0.016666 秒ごと )に描画処理をする作りになっている。

 

赤 1 プロジェクト共用手続き ViewTaskFPS で、全 ViewTask 配列の FPS 進行の計算および描画用 DIB の編集を行う。時間が 1 FPS 以上( 0.016666 秒以上 )経過している場合( ViewTaskFPS 手続きの戻り値 が true だった場合がその意味 )は以下2~4の描画処理を行う。

 

 

赤 2 Wndows 標準 API 手続き GetDC を使って、メインウインドウの描画用コンテキストを取得する。

 

赤 3 Windows 標準 API 手続き BitBlt を使って、メインウインドウの描画用コンテキストに対して  DIB で編集済み画像が入っているコンテキスト g_hDCView の画像データをそのままベタ貼り的に転送。

 

赤 4 Windows 標準 API 手続き ReleaseDC を使って、メインウインドウの描画用コンテキストを解放する。

 

※ 赤2 と 赤4 については Microsoft の仕様の都合。GetDC で描画コンテキストを取得する際は、用件が済んだらいったん ReleaseDC ですぐ解放するよう、その時その時の単位で取得・解放の使い方をするよう( その時に用件が済み次第にいったん解放するという使い方をしないと、つまりそのプロジェクトが Windows 全体のリソース管理に関する描画コンテキストをいつまでも握り続けられると Windows 全体に負荷をかけてしまう原因になるからと見られる )説明されていて、ここは統合前 32 Bit 時代からの定番になる。

 

 

< プロジェクト共用手続き ViewTaskFPS >

 

 

 

ViewTaskFPS の構造をざっと説明すると、01 / 60 FPS 単位( 0.016666 秒単位 )を前提に、処理の負荷の遅れ分も考慮のその単位で何回分の時間経過があったを算出、1 FPS 以上( 0.016666 秒以上 )の進行があった場合は各 ViewTask を進行計算、プロジェクト共用手続き ViewTaskAllocBuild によって描画用 DIB メモリを再構築し、ViewTaskFPS としての戻り値に FPS 描画更新期 であることを伝える true を返す( ViewTaskFPS 手続きは WndProc の WM_TIMER メッセージの契機で呼ばれる前提 )という作りになっている。

 

 

赤 1 Windows 標準 API 手続き timeGetTime を使用し、現在時間を取得( 前回取得時間から今回時間までを観測 

 

赤 2 もし 1 FPS 以上の時間進行があれば、その分の各 ViewTask の進行計算をするためのプロジェクト共用手続き ViewTaskNext に進行分を計算。

 

赤 3 同じく 1 FPS 以上の進行があればプロジェクト共用手続き MouseTaskNext で FPS 進行分を計算。( クリック対象ボタンにマウスが触れた際のふち描画処理 

 

赤 4 もし 1 FPS 以上の時間進行があれば、プロジェクト共用手続き ViewTaskAllocBuild によって、各 ViewTask 状態を元に描画用 DIB メモリへの画像再構築をする。

 

 

< プロジェクト共用手続き ViewTaskAllocBuild >

 

 

 

 

上の緑枠 の手続き内手続き BuildBitblt が、DIB 描画処理の核となる。

 

最下部の 赤1 の所からが ViewTaskAllocBuild としての開始位置になり( それまでの緑枠までは手続き内手続き )、各 ViewTask 配列情報( 各部の配置的な描画管理 )に対して BuildBitBlt 手続きを行う構造になっている。

 

ここで、概要を今一度整理しておくと

 

 ①  WndProc の WM_TIMER メッセージ通知( 定期ループ )の所で ViewTaskFPS を呼び出す

 ②  ( ViewTaskFPS で )1 FPS 以上の進行があれば各 ViewTask 情報の FPS 進行を計算して各 ViewTask 情報による各配置情報を元に DIB 側を画面構成する( 1 FPS 以上の進行があれば各 ViewTask 配列に対して ViewTaskNext を呼んで FPS を進め、ViewTaskAllocBuild を呼んで DIB 画面を構成 

 ③ WndProc の WM_TIMER メッセージ通知( 定期ループ )の所で ViewTaskFPS 手続きを呼び出し後、FPS 進行があれば( ViewTaskFPS の戻り値が true なら ) DIB 画面構成の内容をメインウインドウの描画用コンテキストに反映する

 

という FPS および DIB のこの構造は、慣れないとややこしいかも知れないが概要自体は大して難しい話でもない。

 

赤の方に先に触れるが 赤2 の部分は FPS 情報の文字列構成処理だが、本来はプロジェクト共用手続き StrMenu の方に集約するべき内容だが、混乱を避けるためにここはあえて GraphicBuildTrial の構造と同じような形のままにしておいた。

 

赤3 はプロジェクト共用手続き ViewTextWrite によって、その文字列を DIB 化するための手続き。( 下述する )

 

 

< DIB 描画の核 : 手続き内手続き BuildBitBlt >

 

緑1 その ViewTask 情報が背景の場合の DIB 反映

緑2 その ViewTask 情報が前景の場合の DIB 反映

緑3 その ViewTask 情報が操作/レイアウト関係の場合の DIB 反映

緑4 その ViewTask 情報が透過ウインドウの場合の DIB 反映( GraphicBuild では未使用 )

緑5 その ViewTask 情報が自然3種の場合の DIB 反映

 

緑5の1 の部分は、プロジェクト共用手続き ViewTaskPos と概要は全く同じになるが、これは、DIB 描画処理内ではできるだけ手続き呼び出し( 関数・プロシージャ呼び出し。Windows API も CRT も含める は減らした方が良い理由からになる。

 

前回 GraphicBuildTrial の段階で作られた ViewTaskPos 手続きは、GraphicBuildTrial では、フェードの概念はあったが FPS による連続的な位置移動の概念は無かったため何の問題もなかったが、今回 GraphicBuild では自然3種による FPS ごとの連続的な位置移動の概念も加わる仕様となった。

 

手続き呼び出し( 関数・プロシージャ呼び出し )は、機械語側でいう所の call  および ret で、その1回実行あたりの負荷は大きめで、それを1回実行している間にいくらかのメモリ転送や演算が進められてしまうほどの結構な負荷がある。

 

この話は普段は一切気にする必要などない微小な話だが DIB 描画処理内だけは話は別で、特に Height ( iCntY )と Widht( iCntX ) の矩形( for + for 内 )の中での手続き呼び出しをあちこちでいたずらに増やすと負荷の蓄積の原因となるため、極力避けた方がよい。


for を使った配列参照などでよく使われる、変数に + 1 や-1ずつしていくインクリメントとデクリメントの ++ と -- については、当ブログ筆者はこれまで機械語観が強いと見なして基本は使わない前提でいたが、BuildBitBlt 内においては、負荷をできるだけ減らす理由で使うようにしている。

 

※ CPUも人間と似た所があって

 

   7   インクリメント・デクリメント

  10 + 足し算

  13 - 引き算 

  16 = レジスタに対する数値転送

  25 = メモリに対する数値転送

  60 × 掛け算

 150 ÷ 割り算

 

の順に、電力および速度に負荷がかかる。

 

この負荷推定値は当ブログ筆者の 32 Bit 時代感覚の大雑把な見立て。手続き呼び出しの call および ret は割り算の少なとも倍の負荷になり、特にオブジェクト指向側の仮想関数の呼び出しは内部では call ret を2重3重に呼び出す仕様になっているため、1回の呼び出しあたり400~800近くあると見られる。ただしこれらは旧時代感覚のため近年の 64 Bit CPU は改良されているかも知れない。

 

前回 GraphicBuildTrial と今回 GraphicBuild では、フェードの透過度は8階調を前提にしているため、透過度を計算するためいったん8の割り算をする必要のある箇所を >> 3  演算子に置き換えているのも、割り算を用いるよりビットシフト( 2進数見立てでその数値を3ビット分右にずらすと÷8になる )を用いた方がたぶん若干軽くなるためで、3ビットシフトの推定負荷値はたぶん90~120ほど。

 

この辺りについては繰り返すが、DIB 描画処理のように 1 FPS あたりにメガバイト単位の演算およびメモリ転送をしなければならないという特殊な限定的な話に過ぎず、もちろん普段はこんな配慮など無用に意義・象形を重視した概念間整理を優先することが重要になる。

 

 

< プロジェクト共用手続き ViewTextWrite >

 

今回 GraphicBuild での文字列の DIB 化の手法としては、まず元 BMP 側の

 

 

 

 

赤1 と 赤2 が、これが文字列用枠扱いの横長の白 BMP ファイルで、ここだけ事情が特殊になる。

 

ここだけは、想定の大きさおよび付与情報による文字列の位置を示す役目になっていて、赤1 が右上の背景画像の切替 0?/08 の文字列、赤2 が左上の FPS 表示文字列 の役目になっている。

 

 

 

 

ここで呼ばれている SelectObject、SetTextColor、TextOutW 手続きはいずれも Windows 標準 API。

 

事情が解っていないとこれだけ見てもすぐに解る訳もない所になるが、ここは何をしているのか、以下はあくまで内部イメージ図になるが

 

まず予定位置 Left + 2 Top + 2 に影部分的な黒文字列を BMP 領域に書き込み

 

 

次に予定位置 Left + 0 Top + 0 に本部分的な白文字列を BMP 領域に書き込み

 

 

このような文字列画像を生成することで、明るい背景画像の上に白文字を表示させる際に見えにくくなる問題を、少しは見やすくする工夫になる。

 

 

< 自然3種の仕組み >

 

WndProc のキーイベント WM_LBUTTONUP の所で、プロジェクト共用手続き ViewTaskNatureStart と ViewNatureEnd が開始/停止を意味するが

 

 

 

 

ViewTaskNatureStart の2個目の引き数が、雨なり雪なり桜なりの1度に画面表示される個数の指定になる。

 

各2回にしているのは、前景画( 人物画 )からみた背面側へと前面側への描画の意味になる。

 

ViewTaskNatureStart と ViewTaskNatureEnd による開始設定/開始設定/終了設定については省略し、ViewTaskFPS 内で各行われる各 ViewTask ごとを対象に行われる ViewTaskNext ( FPS 進行計算 )手続き内の、以下 ViewTaskNext 手続きの開始部は省略したその中の自然関係の進行計算の部分を焦点に当てるが

 

 

 

まず下側の 赤2 側の方では、雨( 背景40 + 前景40 = 計80個 ) 雪( 背景20 + 前景 20 = 計40個 ) 桜( 背景10 + 前景10 = 計20個 )のひとつひとつに対し、1 FPS ごとの落下および小さな左右の動きの位置計算をしている。

 

そして上部の 赤1 側は、ひとつひとつの落下位置が画面外の一定の位置に到達した場合に、画面外上部を開始位置に、落下速度と小さめな左右の移動値を乱数( Windows CRT の rand_S 手続き )で設定し直し、このアルゴリズムにより各個数分が、繰り返し落下していく情報を元に、DIB 描画で反映( ViewTaskNature 情報の落下配列に対し、ViewTaskFPS、ViewTaskNext で FPS 進行ごとに計算を進め、ViewTaskBuild の 手続き内手続き BuildBitBlt で ViewTask 情報と結びついている ViewTaskNature の現在位置情報を参照して DIB 反映 )する仕組みになっている。

 

ソース画像は省略するが各自然の開始設定である ViewTaskNatureStart 手続きで、画面外の一定の落下位置に初期化しておくことで、開始初動で 赤1 の判定が行われるという仕組みにしてある。

 

なお、雨と雪は落下速度と左右の移動幅が違うだけのため、固定テーブル変数でまとめることができるが、今回はあえてベタ貼りな作りにしておいた。

 

この中では落下が最も遅い桜に関しては、アニメーション的な画像の順繰り処理も入っているため、アルゴリズムに若干の違いがある。

 

 

 

 

赤1 雨 

赤2 雪

赤3 桜

 

で、雨と雪は4種と6種をランダムに選んでただ落下なのに対し、桜は 005011 ~ 005020 のどこから開始で、どの程度の速度で次に次に画像を切り替え、005020 の次に 005011 に戻る、という作りで、つまり落下速度、左右の移動幅、アニメーション的切り替えの速度を各配列ごとにそれぞれ乱数でバラバラにすることで、自然ぽく見えるようにする工夫をしている。

 

もっと色々と説明したい箇所が多い所だが、ブログ機能の字数制限の都合で1ページ内で収めようとすると厳しいため、今回記事はこれで以上とすることにする。