電子書籍の厳選無料作品が豊富!

VC++6.0、Win32 APIを用いて作成しているダイアログボックスを表示するアプリについてです。

パターン(パターン1~3までの3種類)が格納される列と、文字列(最大256バイト)が
格納される列の2列からなるリストビューがあります。

そのリストビューに新しい情報(行)を追加するたびに、その該当行の情報を
別ファイル(設定ファイル)の構造体に格納し、リストビューの変更・削除があれば、
その都度構造体を更新し(?)反映させたいです。
メモリも無駄なく、効率的に使いたいです。

また次回以降そのアプリを起動させる際には、設定ファイルの内容を読み込んでリストビュー
の表示に反映させたいです。

正直、構造体は苦手なため解らないことだらけなのですが、パターンを格納するint型の変数と
文字列を格納する固定長256byteのchar型配列の変数が必要なのではと思っています。
後は、レコード数を格納するヘッダーも必要なのでしょうか・・・
メモリの取得、開放、移動方法はいまいち分かりません。

現在は、ラジオボタン(パターン用)とエディットボックス(文字列用)を用いて、
リストビューに登録するところまでは出来ています。
変更や削除の機能も実装出来ています。

上記の処理を実現させるための詳細な流れを教えてください。
サンプルコードも載せて頂けると幸いです。
分かりにくい文章で申し訳ありませんが、よろしくお願い致します。

A 回答 (16件中11~16件)

★追記。


・もう少しファイル構造を分かりやすく書いて見ました。
 なお、ファイルタイプは独自のバイナリ・データとします。

+------------+
|管理ヘッダ情報|←固定長ヘッダ
+------------+
|データ並び情報|←可変長データ
+------------+
|データ有無情報|←可変長データ
+------------+
|データNo.0000 |←固定長データ(先頭)
+------------+
|データNo.0001 |
+------------+
   :
+------------+
|データNo.1023 |←固定長データ(最後)
+------------+
※No.0000~No.1023 が実際の構造体データのブロックです。可変ブロックです。

解説:
・データファイルの構造は上から順に
 (1)管理ヘッダ情報(固定長ヘッダ)
 (2)データ並び情報(インデックス配列)
 (3)データ有無情報(有無フラグ配列)
 (4)データブロック(可変長データ)
 となります。
・1つのファイルにパックする場合はこんな感じですが (2)、(3)を別のファイルに
 分離する方法もあります。こちらはデータを拡張するときに別ファイルが増加する
 だけなのでデータ件数が多い場合は拡張しやすくなると思います。
・上記の『データ並び情報』がデータ(No.0000~No.1023)のインデックスになります。
 このインデックスからデータが実際のファイル内の何処に位置するのかが分かります。
 ディスク・システムで言うところの FAT にあたります。
・あと『データ有無情報』はデータ(No.0000~No.1023)が空きデータか、有効データかの
 フラグを管理しているテーブルです。このテーブルを用意したのは削除と登録(追加)
 するときに効率よく(高速に)空きデータを探せるためです。安全のためにデータブロック
 にも空きマーク(削除フラグ)をセットしておきます。これによりデータブロックより
 『データ有無情報』を正しく初期化できるようになります。

その他:
・ファイルのデータブロックがいったん拡張すると収縮することは出来ません。
 収縮する場合はデータブロックのデフラグを行ってファイル構造を再構築する必要が
 あります。これは別の処理やプログラムなどで組み込めば良いでしょう。
・以上。
    • good
    • 0
この回答へのお礼

この度は突然の図々しいお願いにも関わらず、詳細に渡る解説・アドバイスを、
ご丁寧に分かりやすくしていただき誠にありがとうございました。

しかしながら、今の自分では理解できない部分が多すぎるため、これだけのヒントを提示して頂きながら、
このままでは先に進めない状況です。大変情けなく感じております。

例えば、「idString…データのファイル形式を識別するための文字列」がどういうものなのか分かりません。
ファイル形式とは、「テキスト」とか「バイナリ」とかいうことでしょうか?(多分違うと思いますが・・・)

何から何まで教えていただくことは、丸投げしていることと同じですし大変心苦しいのですが、
主要な部分のソースコードだけでも提示していただけると幸いです。
もしそれが無理なようでしたら、この課題をやるにあたって参考になるサイトなどを紹介していただければと思います。

何から何までお世話になりっぱなしで本当に申し訳ないですが、どうぞよろしくお願いいたします。
(ちなみに、大したことではないのですが「データの構造体」の文字列は2つではなく1つです。
紛らわしい書き方ですみませんでした。)

お礼日時:2007/07/26 21:02

★ご要望どおりアドバイスします。


・最初にファイル構造をきちんと決めておきます。
 下記は私が考えているファイル構造です。
 参考に。

ファイル内容:
●ファイル構造の情報(head_t)
 ├データ並びの情報(order[])
 └データ有無の情報(exist[])
●データ内容の情報(data_t)
※構造体の型名は自由に決めてお使い下さい。

// ヘッダの構造体(40バイト)
typedef struct head_t {
 char idString[ 12 ]; // ファイル形式のID文字列(ASCIIZ文字列)
 long headSize; // ヘッダのサイズ(head_t,order[],exit[]の合計)
 long allSize; // 全データのサイズ(oneSize×管理データ数)
 long oneSize; // 1データのサイズ(int,256,256=516バイト)
 long nowData; // 登録データの個数(現在個数)
 long maxData; // 最大データの個数(1024単位)
 long *order; // データの並び順配列(通し番号)
 char *exist; // データの有無用配列(0=無効[データ空き],1=有効[データあり])
} head_t;

// データの構造体(516バイト)
typedef struct data_t {
 int pattern; // パターン番号(1-3,0=無効とか削除用)
 char str1[ 256 ]; // 固定長文字列1
 char str2[ 256 ]; // 固定長文字列2
} data_t;
※構造体のメンバ名も自由に決めてお使い下さい。

解説(head_t):
・この構造体で全データの有効(データあり)、無効(データなし,空き,削除)を管理します。
 データはある決まった数(1024個分)を1つの単位としてディスクのクラスタとFATの様に
 管理されます。これは例え1つのデータでも1つの単位(1024個分)の管理領域がヘッダに
 作られて管理されるという事です。よって1つのデータサイズは 516 バイトですが1つの
 単位分(1024個分)なので516×1024=516キロバイトになります。今回は1つの単位として
 1024個分にしていますが256個分とか、64個分とかを1つの単位にしても良いでしょう。
 数が少なければファイルのサイズが無駄なく抑えられますが、データを追加するたびに
 管理領域を拡張する必要があります。一度にたくさんのデータを追加登録する場合は
 管理領域を一度に拡張させる工夫が必要です。
 (1)idString…データのファイル形式を識別するための文字列(自由に決めること)
  ID文字列が "kenkenpo" ならば char 型配列に[k][e][n][k][e][n][p][o][\0][\0][\0][\x1a]
  となるように格納します。[\0]はNULL文字、[\x1a]は制御文字です。この文字列は最低1個の
  [\0]と[\x1a]を含むようにします。こうするとコマンド・プロンプトの TYPE コマンドで
  ID文字列だけが表示できたり、C 言語で使う文字列なので idString[] をそのまま strncmp で
  比較が出来ます。チェック用に1つの[\0]を入れるということです。
 (2)headSize…ヘッダ情報、データ並び情報、データ有無情報の合計サイズです。
  ファイルの先頭よりhead_t(40バイト)、データ並び情報(4096バイト)、データ有無情報(128バイト)
  の順番に格納されています。その合計サイズ(4264バイト)です。
  なお、データ並び情報はsizeof(long)×maxData個分のサイズです。
  さらにデータ有無情報はsizeof(char)×maxData÷8のサイズです。
 (3)allSize…管理データの全サイズです。つまりsizeof(data_t)×maxData=516 KB
 (4)oneSize…管理データの1つサイズです。つまりsizeof(data_t)
 (5)nowData…管理データの有効な登録データ個数です。最初は0個。最大maxData個。
 (6)maxData…管理データの最大データ個数です。これが単位数。今回は1024個分。
 (7)order…データの並び順です。データ位置を入れ替えたり、ソートしたときに対応するため追加。
  中身はlong型の変数にファイルのデータ構造の通し番号で管理しています。
  よって、リストビューに読み込むときは order[0]~order[nowData-1] までの内容を読み込み、
  この変数値である通し番号を頼りにファイルからランダムアクセスしてデータ追加します。
 (8)exist…データの有効/無効のフラグです。このフラグで管理データの登録/削除を管理。
  フラグ内容は登録(追加)すると『1』、削除や空きデータにするには『0』とします。
  このフラグはファイルのデータ構造の通し番号と同じく順番に対応付けられています。

解説(data_t):
・これがリストビューの1行データの構造体です。
 (1)pattern…パターン番号の情報です。
  1~3が有効値。
  0 は空きデータまたは削除データを表す。
  データを削除する時はファイルの構造体に pattern=0 として書き込み、
  さらにデータ並び順から削除詰めとデータ有無フラグを 0 とする必要があります。
 (2)str1…固定長文字列1です。
 (3)str2…固定長文字列2です。

その他:
・上記の構造体やファイル構造は私が考えたものです。
 こんな感じならリストビューとファイルの構造体がメモリを無駄なく関連付けられると
 思います。メモリを無駄なくするためはリストビューにデータの実体(パターン番号と
 文字列1、文字列2)を管理させてプログラムではリストビューとファイル内の追加、削除
 更新(変更)のやり取りだけを面倒みればいいと思います。
・VTClient さんの4つの回答(アドバイス)をよく読むとリストビューと同じデータを
 独自にリスト構造で管理しています。同じ内容のデータを独自に管理した分だけメモリが
 無駄になっています。また、リストビューとの対応を取るのが面倒だったり、ずれが生じる
 可能性があります。
・よって管理する情報はファイル構造のデータ有無やデータ並びだけを管理してデータの内容
 (実体)はリストビューに任せます。変更する時にリストビューよりデータを取得して書き換え
 このときにリストビューとファイルを同時に更新する操作関数をしっかりと作ります。
・操作関数をはっきりと用意しておけば1つの登録用関数を呼び出すだけでリストビューと
 ファイル内の構造を同時に対応して処理できます。追加、更新、削除、移動、ソートなど。
・以上。一度読み今後の方針をお聞かせ下さい。
    • good
    • 0

対応内容です。



char szPattern[16]→構造体->txBuf
char szBuff[256]→構造体->txBuf

構造体->txBufが重複してますが、パターンが何かは、
nPatternの値を参照してリストビューに反映させればいいのです。
ですから、パターン用文字列は不要と見ています。(節約化)

static LV_COLUMN lvcol→LVCOLUMN(名前違いで、中身まったく同じ)
static LV_ITEM item→LVITEM(名前違いで、中身まったく同じ)
static int nItem→登録ではindex
(static?)int nIndex→変更、削除はindex
static HWND hList→list
static int nPattern→state

エラーについてですが、おそらく「登録」だけでませんか?
私が載せた処理は「常にリストの最後に追加」
の処理にしています。
(1)もし質問者さんが「任意選択位置に“挿入”」しているのであれば IDC_BUTTON1: だけは、nItemを参照させて
常に最後の末尾に追加にすれば直るはずです。
(2)あと、リストビューの自動ソートのスタイルは“なし”
にしてください。

(1)、(2)が気に入らず、どうしても自由位置挿入や
自動ソートにしたいのなら、さらに重い処理追加になりますから
特に(1)は割愛してはどうでしょうか…。
これ以上の追加はリストが非常に長くなり載せられません…。

この回答への補足

<続きです。>
case WM_COMMAND:
switch(LOWORD(wp)){
/* 登録ボタンが押されたときの処理 */
case IDC_BUTTON_ENTRY:
// ラジオグループの状態をチェック
if(Button_GetCheck(hRadio_Pattern1) == BST_CHECKED){
省略
}

GetWindowText(hEdit, szBuff, sizeof(szBuff));
SetWindowText(hEdit, ""); // エディットボックスを空欄にする
nItem = ListView_GetItemCount(hList); // 項目数を取得
item.mask = LVIF_TEXT;
item.pszText = szPattern;
item.iItem = nItem;
item.iSubItem = 0;
ListView_InsertItem(hList, &item);

item.mask = LVIF_TEXT;
item.pszText = szBuff;
item.iItem = nItem;
item.iSubItem = 1;
ListView_SetItem(hList, &item);

// 『変更』ボタンを無効にする
省略
// 『削除』ボタンを無効にする
省略
// エディットボックスにフォーカスを合わせる
省略
return TRUE;

/* 『変更』ボタンが押されたときの処理 */
case IDC_BUTTON_CHANGE:
// ラジオグループの状態をチェック
if(Button_GetCheck(hRadio_Pattern1) == BST_CHECKED){
省略
}
// 選択中の行を知る
nIndex = ListView_GetNextItem(hList, -1, LVNI_ALL | LVNI_SELECTED);
// エディットボックスに表示中の文字列を取得する
GetWindowText(hEdit, szBuff, sizeof(szBuff));
// 選択中の行の表示を変更する
ListView_SetItemText(hList, nIndex, 0, szPattern);
ListView_SetItemText(hList, nIndex, 1, szBuff);
// エディットボックスを空欄にする
省略
// 『変更』ボタンを無効にする
省略
// 『削除』ボタンを無効にする
省略
// エディットボックスにフォーカスを合わせる
省略
return TRUE;

/* 『削除』ボタンが押されたときの処理 */
case IDC_BUTTON_DELETE:
// 選択中の行を知る
nIndex = ListView_GetNextItem(hList, -1, LVNI_ALL | LVNI_SELECTED);
// 選択中の行を削除する
ListView_DeleteItem(hList, nIndex);
// エディットボックスを空欄にする
省略
// 『変更』ボタンを無効にする
省略
// 『削除』ボタンを無効にする
省略
// エディットボックスにフォーカスを合わせる
省略
return TRUE;

以下は、各コントロールが選択されたときなどの、
ラジオボタンやプッシュボタンの有効・無効、
ラジオボタンのチェックの有無に関するコードですので、
省略させていただきます。

補足日時:2007/07/26 10:40
    • good
    • 0
この回答へのお礼

ご返答が遅くなってしまい、申し訳ありません。
対応箇所を詳しく提示していただきありがとうございました。
再び質問で申し訳ないのですが、今回場合物理的なファイルというものは存在しないのでしょうか?
例えば、fopenしてfread、fwriteするようなことはできますでしょうか。
ちなみに、エラーについてですが、まだ解消することができません。
追加は常に末尾にしておりますし、
ソートは”しない”にしております。
元々のソースの一部を載せさせていただきますので、間違っている部分(たくさんあるとは思うのですが・・・)
を指摘していただけると幸いです。
このソースに、VTClientさんのソースを移植することはできますでしょうか。
大変見にくいかとは思いますが、何卒よろしくお願いいたします。

switch(msg){
/* ダイアログ初期化処理 */
case WM_INITDIALOG:
InitCommonControls();
/* 各コントロールのハンドルを取得 */
// ラジオボタン
省略
// エディットボックス
省略
// プッシュボタン
省略
// リストビュー
省略

// リストビューの列の設定
lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvcol.fmt = LVCFMT_LEFT;
lvcol.cx = 70;
lvcol.pszText = "パターン";
lvcol.iSubItem = 0;
ListView_InsertColumn(hList, 0, &lvcol);

lvcol.cx = 600;
lvcol.pszText = "検索文字列";
lvcol.iSubItem = 1;
ListView_InsertColumn(hList, 1, &lvcol);
// 拡張スタイル(行全体選択, グリッド線, 列ドラッグ)
省略
// エディットボックスに入力できる最大文字数を制限する
省略
// ラジオボックスの初期の状態(パターン1にチェック)
省略

return TRUE;
<補足の方に続けさせて頂きます。>

お礼日時:2007/07/26 10:38

FileList構造体は、No.1 参照で修正済みリストです


書き込み/読み込みは、wsprintf関数を使えば簡単です

BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
static HWND list=0;
static int state=1,index=0;
// state=0:未使用 / 1~3:各パターン
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_RADIO1:
state=1;
return 1;
case IDC_RADIO2:
state=2;
return 1;
case IDC_RADIO3:
state=3;
return 1;
case IDC_BUTTON1: // 登録
{
LVITEM cell;
FileList *p,*p2;
int cur,cur2;
char txBuf[15];

cell.mask=LVIF_TEXT;
index=ListView_GetItemCount(list);// 最後の列の次
cell.iItem=index;
cell.iSubItem=0;
cell.pszText=txBuf;
switch (state)
{
case 1:
strcpy(txBuf,"パターンA");
break;
case 2:
strcpy(txBuf,"パターンB");
break;
case 3:
strcpy(txBuf,"パターンC");
}
ListView_InsertItem(list,&cell);
cell.iSubItem=1;
GetDlgItemText(hDlg,IDC_EDIT1,txBuf,sizeof(txBuf));// txBuf=登録文字列
for (cur=0;FList[cur].cur!=index;cur++);// cur=最後の行
for (cur2=0;FList[cur2].type;cur2++); // cur2=挿入用未使用位置
p=&FList[cur];// 対応構造体アドレス代入
p2=&FList[cur2];// 同上
p2->back=(p=p->back);//
p->next=p2;//
p2->cur=index;//
p2->type=state;//上記4行で前後ポインタ更新
for (++cur2;FList[cur2].type;cur2++); // cur2=次回用未使用位置
p2->next=&FList[cur2];//
FList[cur2].cur=index+1;//
FList[cur2].back=p2;//上記3行で次回用調整
p2->txBuf=(char*)malloc(p2->size=strlen(txBuf)+1);// 節約のため可変長文字列は動的確保
strcpy(p2->txBuf,txBuf);//文字列コピー
ListView_SetItem(list,&cell);
SetFocus(list);
return 1;
}
case IDC_BUTTON2:// 変更
{
LVITEM cell;
FileList *p;
int cur;
char txBuf[15];

cell.mask=LVIF_TEXT;
index=ListView_GetSelectionMark(list);// 選択位置
if (index<0) return 1;// 非選択時は終了
cell.iItem=index;
cell.iSubItem=0;
cell.pszText=txBuf;
switch (state)
{
case 1:
strcpy(txBuf,"パターンA");
break;
case 2:
strcpy(txBuf,"パターンB");
break;
case 3:
strcpy(txBuf,"パターンC");
}
ListView_SetItem(list,&cell);
cell.iSubItem=1;
GetDlgItemText(hDlg,IDC_EDIT1,txBuf,sizeof(txBuf));
for (cur=0;FList[cur].cur!=index;cur++); // cur=最後の行
p=&FList[cur];
p->type=state; //更新
if (p->size) free(p->txBuf);
p->txBuf=(char*)malloc(p->size=strlen(txBuf)+1);// 文字列再確保
strcpy(p->txBuf,txBuf);
ListView_SetItem(list,&cell);
SetFocus(list);
return 1;
}
case IDC_BUTTON3:
{
FileList *pf,*p;
int cur;

index=ListView_GetSelectionMark(list);
if (index<0) return 1;
ListView_DeleteItem(list,index);
for (cur=0;FList[cur].cur;cur++);// インデックス先頭検索
for (pf=&FList[cur];pf->cur!=index;pf=pf->next); // 選択位置の対応インデックス
for (p=pf->next;p->type;p=p->next) p->cur--;p->cur--; // 対応インデックス切り詰め
pf->type=0;// 更新
pf->next->back=pf->back;// 更新
pf->back->next=pf->next;// 更新
if (pf->size) free(pf->txBuf);// 不要文字列排除
pf->size=0,pf->cur=0;// 更新
SetFocus(list);
return 1;
}
case WM_INITDIALOG:
for (int i=0;i<100;i++)// 初期化
{
FList[i].size=FList[i].type=0;
if (i) FList[i].back=&FList[i-1]; else FList[i].back=&FList[i];
if (i<99) FList[i].next=&FList[i+1]; else FList[i].next=&FList[i];
}
list=GetDlgItem(hDlg,IDC_LIST1);
・・・

この回答への補足

重ねての質問で申し訳ありません。

今自分のソースに、VTClientさんに教えて頂いたソースを加えている途中なのですが(変数が多少違いますので、所々変更を加えながらやっています)、ビルドは通るのですがダイアログから登録ボタンを押すと画面が落ちてしまいます。

デバッグをしてみると該当行はcase IDC_BUTTON1の中の、
p->next = p2;
の様です。
「CxC0000005:Access Violation」とのダイアログが表示されました。
pの中のそれぞれの値は、「CXX0030: Eroor: 式を評価できません」となっています。

考えられる原因があれば教えて頂ければと思います。
よろしくお願い致します。

補足日時:2007/07/23 13:10
    • good
    • 0
この回答へのお礼

詳細なコードとコメント、本当にありがとうございます。
大変助かります。

この質問をさせていただく前、自分は元々以下のような変数を用意していましたが、
VTClientさんに書いていただいたコードの中に重なるものはありますでしょうか。

LPNMHDR lpnmhdr;

char szPattern[16];// パターン文字列
char szBuff[256]; // 検索文字列(エディットボックス・リストビュー兼用)

static LV_COLUMN lvcol;// リストビューの列に関する構造体
static LV_ITEM item;// リストビューのアイテムに関する構造体
static DWORD dwStyle;// リストビューの拡張スタイルを格納する変数
static int nItem;// リストビューの項目数
int nIndex;// リストビューで選択されている行番号 0,1,2,・・・
static HWND hRadio_Pattern1, hRadio_Pattern2, hRadio_Pattern3,// パターン1, パターン2, パターン3
static HWND hEdit;
static HWND hButton_Entry, hButton_Change, hButton_Delete, hButton_Replace;// 登録, 変更, 削除, 編集(置換)開始
static HWND hList;
static int nPattern; // ラジオボタンの状態を表す変数

また、LV_ITEMとLVITEMは違うものなのでしょうか。

度々申し訳ありませんが、よろしくお願い致します。

お礼日時:2007/07/23 10:14

載せたソースは即興で作成したデバッグ不足のため


誤動作、メモリエラーなどもたまにでますが、
「こんな感じ」という概念だけ観て下さい。

下記のリスト解説ですが抜粋でいきます。
(汚いので理解しない方が良いと思いますが…)

(BUTTON1=ここでは追加)
GetDlgItemText(hDlg,IDC_EDIT1,txBuf,sizeof(txBuf));
エディットフィールドからテキスト内容を取得
while (FList[cur].type) cur++;
ラジオボタン状態が0=空の配列要素インデックスをサーチ
strcpy(FList[cur].txBuf=(char*)malloc(FList[cur].size=strlen(txBuf)+1),txBuf);
テキスト内容はメモリ節約のため動的割り当て
FList[cur].type=state;
状態格納
FList[cur].cur=index;
インデックス格納
pre=cur;
while (FList[cur].type) cur++;
FList[cur].back=&FList[pre];
FList[pre].next=&FList[cur];
入れ替え
(BUTTON2…削除)
for (cur=0;!FList[cur].type&&cur<100;cur++);
for (pFile=&FList[cur];pFile->cur!=index;pFile=pFile->next);
pFile->type=0;
pFile->back->next=pFile->next;
pFile->next->back=pFile->back; … ここまで削除と切り詰め
free(pFile->txBuf); … メモリ開放
for (pFile=pFile->next;pFile->type;pFile=pFile->next) pFile->cur--; … 切り詰め

すみません、解かりにくいですね…。

書き込み/読み込み 処理は例えば...

 配列要素,対応インデックス,バッファ,バッファサイズ,前ポインタ,
 先ポインタ\r\n

のようにするのが無難かと思います。
    • good
    • 0

まず、冒頭で、(ここではリストビュー項目100個にしています)



struct FileList{
int cur;
char* txBuf;
int size;
int type;
FileList *back;
FileList *next;
} FList[100];

のようにして、

BOOL CALLBACK DlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
static HWND list=0;
static int state=1,index=0;
・・・
case IDC_BUTTON1:
{
LVITEM cell;
char txBuf[256];
int pre=0,cur=0;

cell.mask=LVIF_TEXT;
index=cell.iItem=ListView_GetSelectionMark(list)+1;
cell.iSubItem=0;
cell.pszText=txBuf;
switch (state)
{
case 1:
strcpy(txBuf,"パターンA");
break;
case 2:
strcpy(txBuf,"パターンB");
break;
case 3:
strcpy(txBuf,"パターンC");
}
ListView_InsertItem(list,&cell);
cell.iSubItem=1;
GetDlgItemText(hDlg,IDC_EDIT1,txBuf,sizeof(txBuf));
while (FList[cur].type) cur++;
strcpy(FList[cur].txBuf=(char*)malloc(FList[cur].size=strlen(txBuf)+1),txBuf);
FList[cur].type=state;
FList[cur].cur=index;
pre=cur;
while (FList[cur].type) cur++;
FList[cur].back=&FList[pre];
FList[pre].next=&FList[cur];
ListView_SetItem(list,&cell);
ListView_SetSelectionMark(list,cell.iItem);
SetFocus(list);
}
return 1;
case IDC_BUTTON2:
{
int cur;
FileList *pFile;

ListView_DeleteItem(list,index=ListView_GetSelectionMark(list));
for (cur=0;!FList[cur].type&&cur<100;cur++);
for (pFile=&FList[cur];pFile->cur!=index;pFile=pFile->next);
pFile->type=0;
pFile->back->next=pFile->next;
pFile->next->back=pFile->back;
free(pFile->txBuf);
for (pFile=pFile->next;pFile->type;pFile=pFile->next) pFile->cur--;
SetFocus(list);
return 1;
}
・・・
と動的更新して、ファイル書き込みはFList[0]~FList[100]の内容を
FList[0].各項目+改行、FList[1].各項目+改行・・・
のようにして読み込みで先頭オフセットから読み込んでいき、
FList[0].各項目に格納、改行ごとに、
FileList* pIndex;
for (index=0;!FList[index].type;index++);
for (pIndex=&FList[index];pIndex->type;pIndex=pIndex->next){
pIndex->txBuf=(char*)malloc(pIndex->size)・・・

といった感じかと思いますが、汚くてすみません(汗)。
    • good
    • 0
この回答へのお礼

具体的なコードを書いて頂き、ありがとうございます<(_ _)>

しかし、自分の知識不足のため今のところあまり理解できていないのが正直な所です。
これから、頑張って解読しようと思います。

そこで、図々しいお願いだとは思いますが、もし宜しければソースにコメントを
入れて頂けないでしょうか。
何度もご面倒お掛けしてしまい大変申し訳ないのですが、よろしくお願い致します。

ちなみに、ダイアログボックス画面構成は、ラジオボタンが3つのラジオグループ、
エディットボックス、『登録』・『変更』・『追加』の3つのボタン、そしてリストビューです。
普通に登録、変更、削除をすることは出来ています。

リストビューの内容を登録したファイルは、別のアプリからも使いたいと思っています。
具体的には、パターンごとに用意された3つの関数にそれぞれの文字列を引数として
与えるというものです。

今現在その「別アプリ」は、ただパターンごとの文字列配列(今回は3つ)を用意して、
対応する関数に渡しているだけです。
現在作成中の設定アプリから、その文字列の登録・変更・削除をしたいというのが
今回の目的です。

何卒、よろしくお願い致します。

お礼日時:2007/07/21 23:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!