2011-01-13 10 views
2

私はスタックオーバーフローが初めてですが、私はこのサイトで最高のプログラミングソリューションを探しています。だから私は質問する質問があります。メニュー駆動型プログラムでは、グローバルにアクセス可能なデータストレージですか?

私はローカルビジネスクライアント用のTUIメニュー駆動型プログラムであるDelphiでプログラムを作成しています。彼らは私に、1982年のMS-DOSのBASICで書かれた古いプログラムと同じようにユーザーインターフェイスを維持するように頼んだので、グローバルデータがファイルに保存され、プログラムによって再ロードされるメニューがすべて駆動されます。各サブメニューは、それ自体がアクティブメニュー(プログラム)によって実行されるプログラムです。

メニューとサブメニューを表示するための独自のTUIフレームワークとUIマネージャを作成しました。 UIマネージャには、メニューを表示するための "Draw"というオーバーライドされたメソッドと、UIのキーボードイベントを処理する "OnEvent"というオーバーライドされた別のメソッドが含まれています。 私が最初に質問するのは、これがサブメニューを含むメニュー駆動型プログラムを作成するための適切な方法だと思いますか?これがどのように動作するかの例は、次のとおりです。

type 
    TMenu1 = class(TExtendedUIManager) 
    private 
    procedure OnEvent (c: Char); override; 
    end; 

type 
    TSubMenu1 = class(TExtendedUIManager) 
    end; 

procedure TMenu1.OnEvent (c: Char); 
var 
    Next: TExtendedUIManager; 
begin 
    if c = '2' then begin 
    Next := TSubMenu1.Create; 
    Self.Start(Next); 
    Next.Free; 
    end; 
end; 

私の他の質問は、メニュー間でデータを共有するのに適切な方法だろう何ですか?たとえば、メソッドが呼び出されたときにTSubMenu1クラスが文字列を返すようにしたいのであれば、それと対話しない他のサブメニューにどのようにアクセスできるようにするのですか? (質問があいまいであれば申し訳ありません)。私はシングルトンのパターンを念頭に置いていますが、私はまた、UIマネージャーにデータストレージ用のオブジェクトへの参照を格納させ、新しいサブメニューが実行されるたびに新しいサブメニューへの参照を渡すことを考えました(UIマネージャー)。難解なことは、どれが最もうまくいくかを見出すことです。あるいは、私のメニュー駆動のフレームワークがまともであるとしても。

意見は歓迎され、助言をいただきますようお願い申し上げます。あなたの時間と助けてくれてありがとう!

--Todd

+0

標準のDelphiコンポーネントを使用するのではなく、独自のフレームワークとUIマネージャを作成する必要がある理由を説明できますか? 「TUI」とは何ですか?あなたはGUIを意味しますか? – awmross

+0

TUI ==テキストユーザーインターフェイス。それが私だったら、ncursesのようなものを使ってTUIの実装を許容できるものにしたいと思っていますが、DelphiはWindows環境を想定しています。 – sarnold

+0

はい残念ながら私はWindowsを使用する必要がありますが、TUIフレームワークはncursesと同様の目的を果たします。元のプログラムには、すべてのテキストプロンプト(空白の期間、UIごとの複数のプロンプトなど)のような特定のUI特性があるため、自分自身で書きました。WritelnとReadlnは十分ではありませんでした。 – Todd

答えて

0

"私の他の質問は、メニュー間でデータを共有する適切な方法は何でしょうか?"

クラスのメソッドとプロパティを使用してデータを共有できます。これらを使用すると、クラスのインスタンスを作成しなくてもアクセスできます。詳細はthis Linkをご覧ください。

以下は、Listを共有するサンプルコードです。

type 
    TForm1 = class(TForm) 
    --- 
    --- 
    private 
    { Private declarations } 
    class var List: TStringList; 
    --- 
    end; 
var 
    Form1, Form2: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Form1.List.Add('4'); 
    Form2.List.Add('5'); 

    ShowMessage(TForm1.List.Text); 
end; 

initialization 
    StrList := TStringList.Create; 
    TForm1.List := TStringList.Create; 
    TForm1.List.Add('1'); 
    TForm1.List.Add('2'); 
    TForm1.List.Add('3'); 
    ShowMessage(TForm1.List.Text); 


finalization 
    FreeAndNil(TForm1.List); 
end. 
+0

これは、私のプログラミングデザインのためのものです。私のバージョンのDelphi(7.0)では静的インスタンスのフィールドはサポートされていませんが、ルート内でリストを初期化し、メニューツリーの子ノードへの参照によってリストを渡すことにしました。 – Todd

+0

私はようやくこのようなことをすることにしました。私は、新しいメニューや画面を呼び出すたびにコンテキストを渡すだけで、アクティブなデータへの参照(たとえば設定情報、SQLiteデータベース参照、メニュー設定)を格納するContextオブジェクトを作成しました。私はプログラミングコミュニティの中でどの程度受け入れられているのかよくわかりませんが、私は最近、Android APIがどのように機能しているか(「アクティビティ」は特定のコンテキストを通してオブジェクトを呼び出す)に似たものを構築しようとしました。とにかく、すべての助けを借りてくれてありがとう! – Todd

0

私は自由にこれが私のために領土声を出して考えている認めるよ、私の目を引いた最初のものは、このでした:

procedure TMenu1.OnEvent (c: Char); 
var 
    Next: TExtendedUIManager; 
begin 
    if c = '2' then begin 
    Next := TSubMenu1.Create; 
    Self.Start(Next); 
    Next.Free; 
    end; 
end; 

それはのように感じていますこの種のプログラミングの最終条件は、if c = '2' then ... else if c = '3' then ... elseという巨大な意志決定木であるということです。これは書き込みとメンテナンスが面倒です。実行可能な場合、実行する関数を持つ配列の入力文字をマッピングすることはしばしば維持しやすくなります。

新しいキャラクターが登場すると、テーブル内の対応する機能を調べて実行します。完了したら、待っています。

この配列をさらに拡張して、必要な引数と各関数から返される値を追跡できます。関数を実行するときは、戻り値をどこかのグローバル変数に格納し、返された型を追跡します。 (おそらくDelphiの型システムは洗練されていて、それは言及する価値もないほど簡単です)新しい関数を実行するときに、 '現在の'返された結果の型が目的の関数に渡すのに適しているかどうかを確認します。 (タイプが間違っている場合も、グレーアウトメニューエントリが、この組み合わせは動作しないことをユーザーに示すことができます。)

/* key function arg ret types */ 
[['2', foo_create, NULL, FOO], 
['3', foo_delete, FOO, NULL], 
['4', foo_ship, FOO, NULL], 
['d', foo_destroy_all, NULL, NULL], 
['`', foo_return_to_previous_menu, NULL, NULL]] 

私は、これは何らかの方法で有用であると思います。:)

+0

私はあなたがどこから来ているのか理解しています。メニューには、メニューが使用されているかどうかに応じて数値入力または1文字入力が必要なプログラムの部分があります。 Delphi(少なくとも私のバージョン)は、レコードの作成と配列への格納以外に、マッピングの形式はありません。 私が熟考している質問は、サブメニューを格納するためにツリーを使う設計(メインメニューはルートノードです)か、リストの実装を使って同じレベルでそれらをすべて保持するかどうかです。 – Todd