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

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

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

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

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

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

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

このQ&Aに関連する最新のQ&A

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に関連する人気のQ&A

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QYouTubeの再生リスト再生

Android端末で、YouTubeの《再生リスト》を聞く方法が分かりません。

PCでは、《再生リスト》を選択するとリスト通りに次々と
再生されますが、Android用YouTubeアプリで再生すると
一曲で終わってしまいます。

どなたか良い知恵を御教授下さい。

Aベストアンサー

>自動では次の曲に移らない、との見解で宜しいのでしょうか?
はい

ちなみに先ほど書いた操作はYouTubeアプリ限定で、お気に入り再生時には効きません

QVC++5.0とVC++6.0の違いは?

何がどう変わったんでしょうか?
なんとなく使っているだけなのでぜんぜんわかりません。

簡単にんでいいんで思いつくことを書いてもらえるだけでもうれしいです。


よろしくお願いいたします。

Aベストアンサー

MFCのバージョンが違います。MFCのリファレンスを見れば6で増えた機能が分かります。

例えばブラウザを簡単に作れるCHtmlViewは6でないと使えません。

Qyoutubeの再生リスト名の表示順を変更したい

Youtubeについての質問です。
www.youtube.comの再生リストをたくさん作成していますが、
この再生リスト名の表示順を変更する方法はあるでしょうか?
再生リストの名前を変更しても表示順には反映されないようです。
(再生リスト内の動画自体の順番はマウスで変更できますが)

たとえば、
01-再生リストA
02-再生リストB
03-再生リストC
という風に名前順に表示したいのですが。

よろしくお願いします。

Aベストアンサー

こんばんは。
ご自身のチャンネルの、動画の管理をクリック
開いたページの左側に、コミュニティというのがあります。
コミュニティをクリックすると、コメント メッセージってありますので
メッセージをクリックして下さい。
そこで確認出来るようになっていますので。

QVC++6.0からVC++.NETへの変遷について

VC++がようやく分かり出したこの頃ですが、今日本屋に立ち寄ったら、なっ なんとVC++の本がほとんど無くなり、代わりにVC++.NETとVC#ばかりになっていました。

C#はVC++とは違うと聞いていたのですが、読んでみるとVC++.NETもかなり違ってました。
(かなり違うという表現は、各人の状況により意見が異なると思いますが)

私のような本を見ながらコードを打って勉強している初心者にとって、VC++.NETの本ではVC++6.0を動かすことができません。

今から勉強する人や本を買って勉強しようとしている人あるいは、コンパイラを手に入れようとしている人はVC++.NETに移行してしまわざるを得ないのでしょうか?

すでにVC++6.0を十分活用出来ている人も、時代の流れでNETやC#を勉強していかなければならないのでしょうか?

つまり、単なるバージョンアップとは一線をなす変更がなされたということなのでしょうか?

良くご存知の方見解をお願いします。

Aベストアンサー

すぐにではありませんが、.NETに移行せざるを得なくなるでしょうね。
ただ、開発環境という面では、VS.NETにはC++が含まれており、C++の部分は
従来のC++も利用できるようになっていて、これはアンマネージC++と呼ばれています。
C++で.NETのコードを作成する時は、マネージC++という拡張仕様で記述します。
また、従来のコードと.NETフレームワーク用コードを混在させてアプリケーションを
開発することもできます。これは、相互運用という形で説明されています。

ということですので、C++で習得したものが無駄になることはありません。
たぶん、.NET環境の開発には、C++よりもC#やVB.NETを利用することが
多くなると思いますが、C++を理解していることはプラスにはなってもマイナスには
なりませんので、頑張って下さい。

.NET関連のサイトを2つご紹介しておきます。ご参考に。
http://www.microsoft.com/japan/msdn/library/default.asp
http://www.atmarkit.co.jp/fdotnet/index.html

すぐにではありませんが、.NETに移行せざるを得なくなるでしょうね。
ただ、開発環境という面では、VS.NETにはC++が含まれており、C++の部分は
従来のC++も利用できるようになっていて、これはアンマネージC++と呼ばれています。
C++で.NETのコードを作成する時は、マネージC++という拡張仕様で記述します。
また、従来のコードと.NETフレームワーク用コードを混在させてアプリケーションを
開発することもできます。これは、相互運用という形で説明されています。

ということですので、C++で習得したもの...続きを読む

QYoutube 再生リスト 著作権違反?

初投稿になります。
Youtube を利用している上で分からないことがあるので
皆さんの力をお借りしたいと思います。よろしくお願いします。

Youtube の機能の1つに再生リストを作成する機能がありますが、
(1)Youtube で配信されている公式MV(例えばVEVOやVictor music Channel)の動画を
使用して、自分でお気に入りの動画として再生リストを作成するのは
著作権違反になりますか?
(2)また、その再生リストをを他人が見られるように「一般公開」扱いにするのは著作権違反になりますか?(もちろん配信元を明記した上で)

Youtubeの動画で、TVやMVを勝手に複製してアップロードすることが違法であることは分かり
ますが、再生リストについては不明なのでお尋ねします。最近ではブログに動画を載せているのも多々見ますので、違反でないのだろうかとも思ってしまいます。
ご回答お待ちしております。
補足
Youtubeのヘルプセンターは一通り見ましたが、自分の探している回答が見つからなかったので
知っていらっしゃる方、どうか教えていただければと思います。

初投稿になります。
Youtube を利用している上で分からないことがあるので
皆さんの力をお借りしたいと思います。よろしくお願いします。

Youtube の機能の1つに再生リストを作成する機能がありますが、
(1)Youtube で配信されている公式MV(例えばVEVOやVictor music Channel)の動画を
使用して、自分でお気に入りの動画として再生リストを作成するのは
著作権違反になりますか?
(2)また、その再生リストをを他人が見られるように「一般公開」扱いにするのは著作権違反になりますか?(もちろん配信元を明...続きを読む

Aベストアンサー

>(1)
 ・公式動画に関しては著作権違反にはなりません
 ・著作権違反の動画についても見るだけなら違法にはなりません
>(2)
 ・私的利用の範囲を超えるので違法になります・・但し罰則の対象にはなりません

・私的な範囲内の利用は問題有りません・・・再生リストを自分で見る
・私的な範囲内を超えた場合は(文化庁のQ&Aの文言だと「家庭内その他これに準ずる限られた範囲内」)
 著作権違反になります・・・・再生リストを公開する(公式動画、違法動画のどちらも)
・>最近ではブログに動画を載せているのも多々見ますので、違反でないのだろうかとも思ってしまいます・・・厳密には著作権法違反(ただ罰則はありません)
・現実には違法動画に関しては著作権者がup先から削除させたり(プログ等での公開の元を絶つ)
 公式動画に関しては著作権者が宣伝になるので(プログの動画とか)放置しているだけでしょう

QVC++2005 VC++6.0で使えた関数がつかえない?(たとえば、GetModuleFileNameとか、、)

VC++超超初心者です。

いままであったVC++6.0で利用できていた、VC++2005で
GetModuleFileNameができなくなりました。
(利用できないことなんて、ないと思いますが、、、)

何か宣言とかinclude文とか必要なのでしょうか。

すみませんが、よろしくお願いします。

Aベストアンサー

VC++2005無料版にはPlatformSDKが別になっているのでそのままでは使えません
別にPlatformSDKをインストールしてVC++2005の設定を変える必要があります
VC++2008では無料版にもSDKが付属しています

QYouTube コメント欄 再生リスト名表示

YouTube再生リストに追加してからリストからその動画に飛びコメントしても ナイス! イマイチ の横に登録した再生リスト名が表示されません。表示させる方法教えて下さい

Aベストアンサー

再生リストに入れている動画の再生の仕方によるのかなと思います。

1.自分のチャンネル内で再生リストから再生しコメントを入れる場合

2.ダイレクトに通常検索で表示させて再生する場合

このどちらかにより同じ動画をチャンネル内で再生リストから選択して
そこで再生させながらコメントする場合と

再生リストに入れている動画なんですが
ダイレクトに検索してコメントを書き込む場合で

コメント横に表示したりしなかったりなるんだと解釈しています。

Qvc++6.0 と vc++2500

vc++6.0で

ifstream ifs("userkey.dat");
ifs.getline(oc_user1, 63);

となっていてコンパイルできていたのですが

2005にしたら
コンパイルできません
どうしたらコンパイルできますか

6.0と2005の違いを知るには何を読んだらいいでしょうか?

Aベストアンサー

std::ifstream ifs("userkey.dat");
ifs.getline(oc_user1, 63);

としてみてはいかがでしょうか。

QYouTubeの再生リスト「後で見る」のリネーム

YouTubeの再生リスト「後で見る」の名前は変更出来ますか?
以前は変更出来たと思うんですが…(そのリストは今も残っています)

また、再生リストAから再生リストBに複数の動画を一度に移動する方法もあれば、教えて下さい。
もし外部のツール、補助的なサイトもあれば、そちらでも構いません。

Aベストアンサー

こんにちは。

自分も以前から「後で見る」とその名前の変更機能を時々使っていて、最近使おうとしたら出来なくなっていて困っていました。そこで試行錯誤していたらやり方がありました。
 補足:以前は他の再生リストと同様の操作で出来ていたと思います。

1. YouTubeの画面右上の自分のログイン名をクリックします。
2. すると自分の再生リストが表示されるので「後で見る」のサムネイルをクリックします。
 →「後で見る」に入っている動画が一覧表示されます。
  ここまでは以前と変わってないように思います。

3. 一覧の動画のいずれかをクリックします。
 →動画が再生されると共に、ブラウザの下にサムネイルの表示された横長のバーが出ます。

4. 上記のバーの右上のほうに「オプション▲」という部分があるので、クリックして「新しい再生リストとして保存」を選びます。

5. 「再生リストのタイトル」に好きな名前をつけて「保存」ボタンをクリック

これで「後で見る」が任意の名前の再生リストになります。

どうして動画を再生しないと出来ないようにしたんでしょうね。
前より少し面倒になりましたね。自分もやり方を見つけて安心しました。
PCで見つけた動画を追加してテレビで見るときに便利だったので使ってました。

こんにちは。

自分も以前から「後で見る」とその名前の変更機能を時々使っていて、最近使おうとしたら出来なくなっていて困っていました。そこで試行錯誤していたらやり方がありました。
 補足:以前は他の再生リストと同様の操作で出来ていたと思います。

1. YouTubeの画面右上の自分のログイン名をクリックします。
2. すると自分の再生リストが表示されるので「後で見る」のサムネイルをクリックします。
 →「後で見る」に入っている動画が一覧表示されます。
  ここまでは以前と変わってないように思い...続きを読む

QVC++6.0からVC++.NET2005へ移植

VC++6.0で作成したプログラムをVC++.NET2005に移植しました。
ビルドを行うと『fatal error LNK1104:ファイル'mfc42.lib'を開くことができません。』のエラーが出てしまいます。
ソリューションのプロパティを見てもどこで「mfc42.lib」の参照を定義しているのか分かりません。
どこで「mfc42.lib」の参照を定義しているのか教えてください。また、対策を教えてください。

Aベストアンサー

VC++.NET2005のエディションをお教えください。
Express Editionでは、リソースエディタがない、
ATL, MFCが使えないなどの制限がいくつか存在します。

また、VC2005などでは.NET Frameworkの開発が前提となっており
WIN32APIを使用する場合などについては、Platform SDKを
インストールする必要があります。


人気Q&Aランキング

おすすめ情報