Systemicusパート2:GUI





このトピックを続ける投稿。 1か月ほど前に、Systemicus OSとグラフィカルインターフェイスとの遅い類似性を示しました。 この間ずっと(自分の自由になったとき)改善に取り組み、結果を一般に公開しました。 おそらく、この記事はGUIの開発に役立つでしょう。なぜなら、 このトピックのいくつかの側面に関する良い資料は見つかりませんでした。





一般的な結果



前のトピックで約束したように、パフォーマンスの薄い場所(またはむしろ場所) 見つけました-それらはスケジューラ(循環的)であり、すべてのウィンドウの二重再描画のエラーであることが判明しました。

反結果は、シェル実行可能ファイル(explorer.exe)のサイズの問題でした。 私はすべてのシェルコードをPEの1つのセクション(4096バイト)に収めることを望んでいましたが、これまでのところこれは実現していません。 現在、コードセクションは4,800バイトです(ファイル自体の重量は約10 KBです:-()。将来サイズを少し小さくすることは可能かもしれませんが、シェルに追加する必要があるため、explorer.exeのサイズに達することさえあります。 16キロバイト。



動作原理



すぐに、私は貪欲な人が2回支払うことに注意します。 余分なキロバイトのRAMを節約したいため、最初にバイトスクリーンマスクを作成する方法を拒否しました(各ピクセルはウィンドウ番号を持つウィンドウに対応します[ウィンドウは最大256個提供されます])。 また、問題はメモリの節約だけでなく、プロセッサリソースの節約にもあります。これは、このテクノロジがない場合、各画面ピクセルが特定のウィンドウに属しているかどうかを確認する必要がないためです。 しかし... ...クリッピング(つまり、別のウィンドウの下にあるウィンドウの一部のみをレンダリングする)に至ったとき、私は自分がどれほど深く誤解されているかを認識しました。 描画されているウィンドウが1つのウィンドウの下にある場合-そこにクリッピングを計算できる-単なる長方形の領域があるとよいでしょう。 しかし、描画中のウィンドウが他のいくつかのウィンドウで一度に最もわいせつに重なり、描画されている領域が非常に奇妙であることが判明した場合はどうでしょうか?

一般に、戻って画面のバイトマスクを入力しました。 メモリ消費量は増加しましたが、コードの量は減少しました(計算が容易になりましたが、速度が増加したことを意味するわけではありません)。



だから、すべてが不名誉に簡単です。 ポイントがウィンドウに属する場合、各ピクセルにゼロ値が割り当てられるか、そうでない場合は、バイトスクリーンマスクがあります。 ウィンドウ構造があり、次のようになります。



WNDLIST_ITEM: .handle dd 0 ; +00 .x dd 0 ; +04 .y dd 0 ; +08 .width dd 0 ; +12 .height dd 0 ; +16 .flags dd 0 ; +20 .rsrc dd 0 ; +24 .parent dd 0 ; +28 .wbmp dd 0 ; +32 .caption dd 0 ; +36 ; if DESKTOP: db Leftbuttonstate ; +36 ; db RightButtonState ; +37 ; dw reserved ; +38 .clickx dw 0 ; +40 .clicky dw 0 ; +42 .winstyle dd 0 db 16 dup 0
      
      





親とwinstyleの値は未使用であり、予約済みであることが判明しました(16バイト後も同様)。 このデータを使用して、非表示のwbmpバッファーにウィンドウを構築できます(ダブルバッファー技術)。 バッファのメモリを節約するために、すべてが8ビットカラーで描画されます(これまでは16のみが使用されていました)。 ポイントごとに1バイト。画面に表示される場合、この色はカラーマッチングテーブルを使用して24/32ビットに変換されます。



さまざまなウィンドウイベントが発生した場合のすべての描画操作はバッファで発生し、バッファ全体(または部分的に)が画面に表示されます。 画面に直接描画されるものは何もありません(テキスト、ボタンなど)。



次に、ウィンドウ要素について説明します。 すべてのウィンドウのすべての要素には、要素の共通グローバルテーブルが1つだけあり、その各要素にはウィンドウへのリンク(合計256個のウィンドウしかないため、1バイト)、ウィンドウに対する相対位置、要素サイズ(各2バイト)、ステータスバイト、2ダブルワード-リンク(たとえば、ボタンまたは他の要素のその他の情報へのテキスト)および追加(ボタンのアイコンまたは要素のタイプに応じたその他のデータ)。 ステータスバイト:下位4ビットは要素のタイプ(ボタン、チェックボックス、テキストフィールドなど)を示し、その状態(アクティブかホバーか)で最も古いものです。



メインエクスプローラープロセスは、マウスドライバーからイベントを受け取ります。 何が起こるか:ウィンドウはポインターの座標によって検索されます。 ポインターのパラメーターはウィンドウに渡されます。つまり、キーが押されているかどうか、押されている場合は、キーを押すか離すことです。 最初にクリックすると、ウィンドウがアクティブになります。 アクティブにし、フォアグラウンドで再描画します。 次に、要素のグローバルテーブルで、ウィンドウに属するすべての要素と、それらの要素(マウスの座標の下にある要素)を探します。 見つかった場合、処理するマウスポインターのパラメーター(描画、再描画など)に従って。

ポインターがウィンドウの外側にある場合、このイベントも処理されます。 この場合、デスクトップでキーが押され、[スタート]メニューが開いている場合は、それを閉じる必要があります。 将来、これらのイベントはショートカットやその他のデスクトップ機能を作成するために必要になります。



この機能により、イベントの処理、ウィンドウのドラッグ、ウィンドウオーバーレイのクリッピングなど、単純なシェル関数を実装することは難しくありません。



近い将来の計画



現在の実装には多くの問題があります。特に、デスクトップをクリックした後にマウスカーソルを描画するとエラーが表示されることがあります-カーソルのコピーがテーブルに残ります)。

重要なのは、スクロールテキストを備えた本格的なtextarea要素、同じ名前のラジオボタンの関係(つまり、radiobuttonsグループに一度に1つのボタンのみを含める)です。 これは難しいことではありません。 興味深いがそれほど難しくないタスクは、アプリケーションをウィンドウにバインドすることです。 現在、これらはすべてシェル自体によって表示されるテストウィンドウです。



ウィンドウを作成し、アドレス0xB8000からコンテンツをコピーする(当然、各文字を8 * 16のピクセル領域に変換する)ことで端末を実装するというアイデアがあります。



次に、いくつかのアプリケーションを移植します。まず、fasmw、小さなおもちゃ、そしておそらく電卓を移植します。 その後、尊敬されるhabrasocietyの購読を解除します。



そして最後に、短いビデオ。 いいえ、ビデオを投稿できません。なぜなら、 CamStudioはQemuを本当に遅くします。 Qemuを実行するために画像を投稿します。 パーティション2、任意のモードを選択しますが、640 * 480には背景にわずかな問題があります)scられないでください、これはALPHAです...多くのバグ。 あなたはベータ版をscるでしょう:-)また、私はスタイルと間違い(もしあれば)をおizeびします、それはすでに深い夜です...



ファイルへのリンク: http : //nebka.ru/files/647-0.02_qemu.7z



All Articles