先日完成したソフトを公開したのですが、Windows98ユーザーの方から起動時に
「Exception EReadError in module ****.EXE at ********.
ComboBox**.Items.Strins の読み込み中のエラー
:A call to an OS function failed.」
というエラーが出て起動しないと言われてしまいました。
同じ症例が数件あるのですが、何か原因の特定はできるでしょうか?
検証してくださった方がいるのですが、何か一つでも常駐ソフトがあると
上記エラーが出るそうです。
エラーが出たのはWIN98のファーストエディションでは?
Delphi標準のコンポーネント以外を使用する場合、内部でどのような
ことをやっているか、API等仕様していないか把握していないと
このような現象はままあります。特にWindowsのOSによってカーネルの
バージョンが違いますから、動く動かないは当然発生します。
相手の環境をよく把握して、再現と原因を把握するのであれば
自分にその環境がなければ難しいでしょうね。
特にネット上で公開するのであれば、自分で動作確認した環境のみを
動作保証しなければならないでしょう。
ぺんたさんありがとうございます。
コンポーネントは標準の物しか使っていません。
Win98のファーストかどうかはユーザーの方に聞いておくことにします。
やはりOSの壁で非サポートというのはある程度妥協しなければだめなようですね。
熟練者の方はどうにかクリアすることもできるのでしょうけど。
一応OS毎の動作状況のアンケートを採って検証してみたいと思います。
ありあとうございました。
Halbow です。
> やはりOSの壁で非サポートというのはある程度妥協しなければだめなようですね。
標準コントロールではそんなことはあり得ません。
Delphi のバージョンにもよりますが、Windows95 は D6 以降、サポート外と
いうことはありますが、Windows98 で標準コントロールが使えない、という
ことは聞いたことがありません。どのように、TComboBox の Items を設定して
いるのでしょうか? Delphi のバージョンも教えてください。D7でしたら
バグということもあり得ます。
Halbowさんこんにちは。
> 標準コントロールではそんなことはあり得ません。
なるほど。
ということはOSレベルの問題じゃないかもしれませんね。
> どのように、TComboBox の Items を設定しているのでしょうか?
キー設定を登録する項目なので、インスペクタの所で下のように書いてあります。
F1
F2
F3
・
・
A
B
C
・
・
ScrollBoxにCheckBoxを270個、ComboBoxを90個入れているのですが、それが
多すぎるのでしょうか?
編集している時もPCがかなりもたつくので。
MOStringGridの正しいインストールの仕方も使い方もわからないので上記のような
無理矢理な事をしています。
> Delphi のバージョンも教えてください。
バージョンは6のPersonalです。
どのような状況になっているのかは↓にありますので、宜しければ見て頂けますか?
http://inc.s35.xrea.com/tool/file/uocm/uocm030.lzh
リソース不足ですね。
コンボボックスを1つにして、他はオーナードローに任せるなどしてみてはどうでしょう。
Halbow です。
> ScrollBoxにCheckBoxを270個、ComboBoxを90個入れているのですが、
> それが多すぎるのでしょうか?
にしのさんご指摘のようにこれではリソース不足になりかねません。
魔法の種類が90で、そのおのおのに CheckBox が3こと ComboBox が1こ
必要なのですね。これは、まえのところのキーのカスタマイズのためでしょうね。
わたしだったら、魔法の種類を選択するリストボックスか ComboBox を一つと、
あとは、それで選ばれた一つの魔法に対する CheckBox が3こと ComboBox が1この
計5個のコントロールと、選ばれている魔法の種類を表示する Label と
ユーザが設定したキー設定を表示する TMemo 1つの計7個でくらいにする
と思います。
お二方ありがとうございます。
ということは、UserSpellのページもListBoxとComboBoxとMemoの3つを使った方が賢明ですね。
ですが、これらのやり方がさっぱり思いつきません(^-^;
ListBoxのアイテムを選択したらComboBoxのItemIndexを現在設定しているものに合わせて、その結果をMemoに表示するというので良いのでしょうか?
プログラミングを始めてから1ヶ月、難しいことは避けてきてばかりだったので今回はかなり大変そうです。
よろしければ何か有用なヒントでもいただけるとありがたいです。
とりあえず今から自分なりに試行錯誤してみようと思います。
とりあえずUserSpellのページの試作を
http://inc.s35.xrea.com/a.png
http://inc.s35.xrea.com/Unit1.pas
こんな感じで頑張って作ってみたのですが、ComboBox1ClickのList1Atai[0] := 0; の部分がきちんと代入されません。
ちゃんと右側のMemoは書き換わっているんですが、もう一度ListBoxで同じ物を選択してみると、全く変化していません。
もっと良い方法があると思いますが、素人の僕にはこれが限界でお手上げです。
どうかご教授ください。
Halbow です。
とりあえず、ComboBox1Click() と ListBox1Click() でなにをしたいのか分か
らないので、
http://inc.s35.xrea.com/Unit1.pas
の部分を添削しておきました。ComboBox1Click() は ComboBox1Change() だと
思います。ご自分のコードと見比べてください。
var
Form1: TForm1;
List1Atai:array[0..9] of integer;
implementation
{$R *.DFM}
const
WU: array[0..8] of string = ('None','Clumsy','Create Food','Feeblemind','Heal',
'Magic Arrow','Night Sight','Reactive Armor','Weaken');
procedure TForm1.FormCreate(Sender: TObject);
var
i : integer;
begin
ListBox1.ItemIndex := 0; //リストボックスの一番上を既定で選択
for i := 0 to 8 do List1Atai[i] := i;
List1Atai[9] := 8;
// iniファイルがないので上記で初期化したものとする
ComboBox1.ItemIndex := List1Atai[0]; //リストボックス一番上の値をセット
Memo1.Clear;
for i := 0 to 9 do begin
Memo1.Lines.Add('U'+Format('%.3d : ',[i+1])+WU[List1Atai[i]]);
end;
end;
procedure TForm1.ComboBox1Change(Sender: TObject);
var
i,j:integer;
begin
i := ListBox1.ItemIndex;
j := ComboBox1.ItemIndex;
Memo1.Lines[i] := 'U'+Format('%.3d : ',[i+1])+WU[j];
List1Atai[0] := j;
end;
procedure TForm1.ListBox1Click(Sender: TObject);
begin
ComboBox1.ItemIndex := List1Atai[ListBox1.ItemIndex];
end;
> 素人の僕には
わたしもアマチュアです。是非、めげずにがんばってください。
すみません、訂正です
List1Atai[0] := j;
のところは
List1Atai[j] := j;
です。しかし、List1Atai[j] := j; これになんの意味があるのでしょう?
これなら j 番目の配列要素は必ず j になっていますよね。
Halbowさんありがとうございました!
色々ごちゃごちゃとやってみてなんとか上手くいきました。
> List1Atai[j] := j; これになんの意味があるのでしょう?
これは、メインのフォームでTImageのTagごとに魔法を割り振ってあるので、
OKボタンを押して設定を確定した時に、TImage.TagにList1Atai[i]を代入
しようと思ったんです。
'List1Atai'というのは「リスト1の魔法毎のコンボボックスのItemIndex」
という意味で適当に名付けました(^-^;
あとは問題のユーザーキーのページです。
同じように応用すればなんとかなりそうですが、チェックボックスのBooleanが
厄介そうです。
とりあえずまた試作を色々考えて作ってみることにします。
ありがとうございました。
Booleanは思ってるほど厄介ではなかったんですが、iniの読み込み時の記述の
仕方がわかりません。
for i := 1 to 90 do begin
List2AtaiCtrl[i] := Boolean(Ini.ReadInteger('UserKey', 'CTRL'+i, Byte(List2AtaiCtrl[i])));
List2AtaiShift[i] := Boolean(Ini.ReadInteger('UserKey', 'SHIFT1', Byte(List2AtaiShift[1])));
List2AtaiAlt[i] := Boolean(Ini.ReadInteger('UserKey', 'ALT'+i, Byte(List2AtaiAlt[i])));
List2AtaiKey[i] := Ini.ReadInteger('UserKey', 'KEY'+i, List2AtaiKey[i]);
end;
iの使い方がまだイマイチよくわからず、真ん中の'CTRL'+iの部分がうまくいきません。
'CTRL'+'i'とか'CTRL'+[i]とか色々試してみたのですが、ダメでした。
あと、コンポーネント名にはiなどの変数が使えるのでしょうか?
たとえばComboBox001とするとComboBox+Format('%.3d',[i])のような感じにはできないのでしょうか?
iは整数型ですよね。
そして'CTRL'は文字列。
例えば、Delphiから離れますが、計算式で
'いろは' + '123'
と書けば、
'いろは123'
となることはわかりますよね。
では、
'いろは' + 123
は?
文字列'いろは'に対して、数値である123を足すことはできませんよね。
123という数値を文字列にしなければなりません。
数値から文字列に変換する関数はいろいろあります。
IntToStr, FloatToStr, Formatなど。
前に0を付加しないで、123を'123'としたいのであれば、IntToStr(整数型から文字列型への変換)を使用します。
つまり、
'CTRL' + IntToStr(i)
となります。
Booleanの読み込みは、ReadBoolがありますよ。
使い方はReadIntegerとほぼ同じです。
# 引数の型、戻り値の型が違うだけです
にしのさんありがとうございます。
すごく簡単な事でしたね(^-^;
すっかり忘れていました。
ReadBoolもあること知りませんでしたー。
おかげさまでなんとか実装できてきました。
あとは
> コンポーネント名にはiなどの変数が使えるのでしょうか?
> たとえばComboBox001とするとComboBox+Format('%.3d',[i])のような感じにはできないのでしょうか?
これなんですが、何か良い解決法はあるのでしょうか?
よろしくお願いいたします。
あと、「iniファイルの[***]というセクションが存在しなかったら」という条件指定
はできるのでしょうか?
ComboBox+Format('%.3d',[i])ではなく、
FindComponent('ComboBox' + Format('%.3d',[i]))
こんな感じですね。
ヘルプを参照してください。
それと、セクションの存在チェックですが、ヘルプは見ましたか?
せめてヘルプくらいは読みましょう。
ヘルプは一通り検索してみたんですが、検索ワードが悪かったようで見つけられませんでした。
次からはもう少し丹念に調べてみることにします。
申し訳ありませんでした。
でも、おかげさまで疑問は全て解決しました。
本当にありがとうございました。
忘れていました、一応解決です。
ツイート | ![]() |