コンボボックスの編集で苦戦しています

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
メッセージ
作成者
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

コンボボックスの編集で苦戦しています

#1 投稿記事 by yama »

いつも勉強させていただいています。またお教えいただきたいのですが。

使用したいのはデフォルトタイプのComboBoxです
'comboにデーターを読み込む
'comboの指定行を選択状態にする
'何行目が選択されているかを取得
など基本的な部分はパワーユーザーなどのホームページを参考に何とか動く様になりました。リスト部分のある行をクリックすると、エディットボックス部分に全選択状態で入りますが、うまく動かないところは、エディットボックス部分の編集時で

1.初期化時に入力した文字列を一部削除するとエディットボックスが見た目空になってしまい続けて入力ができません。編集は正しく行なわれておりリスト部には正しく表示されます。リストの該当行を再度クリックするとまた全選択で表示はされます。
2.初期化時に入力した文字列に追加挿入しようとすると1文字は入るが2文字目に「未知の文字列が解放されようとしました。」となってしまいます。
3.コントロールの幅以上には編集の入力ができないのは仕様でしょうか?
数年前も組み込みに挑戦しましたが挫折していて、再挑戦しましたが又つまづいております。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの編集で苦戦しています

#2 投稿記事 by 7 »

> 3.コントロールの幅以上には編集の入力ができないのは仕様でしょうか?
これはコンボボックスのプロパティ「水平オート スクロール」にチェックを入れます。簡単ですね。

> 1.初期化時に入力した文字列を一部削除するとエディットボックスが見た目空になってしまい続けて入力ができません。編集は正しく行なわれておりリスト部には正しく表示されます。リストの該当行を再度クリックするとまた全選択で表示はされます。
> 2.初期化時に入力した文字列に追加挿入しようとすると1文字は入るが2文字目に「未知の文字列が解放されようとしました。」となってしまいます。
「初期化時」っていうのはクリエイト時のことでしょうか?
よく分からなくて、その状況を再現できずにいます...もっと詳しく書いて頂ければと思います。

解決にはならないんですけど、GetDlgItem()関数を多用するなら変数に保管するといいですよ。
ゲスト

Re: コンボボックスの編集で苦戦しています

#3 投稿記事 by ゲスト »

> > 3.コントロールの幅以上には編集の入力ができないのは仕様でしょうか?
> これはコンボボックスのプロパティ「水平オート スクロール」にチェックを入れます。簡単ですね。

これは目からうろこ、さんかくマークがつくのだと思ってました。

> よく分からなくて、その状況を再現できずにいます...もっと詳しく書いて頂ければと思います。

実行できるコードまとめてみます。それをまたみていただけますか?言葉では
伝えるのが難しい。

> 解決にはならないんですけど、GetDlgItem()関数を多用するなら変数に保管するといいですよ。

たしかに非常に見易いですね。さっそく取り入れさせてぃただきます。
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

Re: コンボボックスの編集で苦戦しています

#4 投稿記事 by yama »

上のメッセージ、ログインしてませんでした。

> > 1.初期化時に入力した文字列
は端に選択されエディットボックスに表示された文字列で、初期化<=立ち上げ時に文字配列へ文字をセットすることを意図してました。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの編集で苦戦しています

#5 投稿記事 by 7 »

ちょっとコード変えちゃいました。 SetCombo()関数は要らないと思ったので消しました。他に使い回すなら消さなくてもいいです。
あと、hComboをグローバルにしました。大したことのないコントロールなら毎回取得してもいいんですけど、コンボボックスが大事なコントロールなのかと思ったので...。

ポイポイっとソースを置いていくのは簡単だけど、説明するのって難しい...。
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

Re: コンボボックスの編集で苦戦しています

#6 投稿記事 by yama »

> ちょっとコード変えちゃいました。

ありがとうございます。とりあえず実行できるようにしてためしてみました。
コードの中身はじっくり時間をかけ勉強させていただきます。希望する動作
はほぼ実現されました。文字途中に挿入する際カーソルが末尾に移動してしまうので
ヘルプを見て MainWnd_ComboBox1_EditChange()内にて

Dim Modori As Long ' もどり値
Dim Hajime As Long ' カーソルの始めの位置
Dim Owari As Long 'カーソルの終わりの位置
' カーソルのポジションを取得
Modori=SendMessage(hCombo,CB_GETEDITSEL,Hajime,Owari)
などとしてみましたが、どちらも0で取得できませんでした。ヘルプが読みこなせない
のですが、Hajime,Owariに取得できるのですか?もどり値の32ビット値を分解?
WEBで検索をかけてみましたがかなりディープなのか日本語ページもすくなくて
しょぼん状態です。

> ポイポイっとソースを置いていくのは簡単だけど、説明するのって難しい...。

ポポイトおいていただいたソースこそお宝なのです。感謝
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの編集で苦戦しています

#7 投稿記事 by 7 »

> 文字途中に挿入する際カーソルが末尾に移動してしまうので
あー。そうですねっ。気付きませんでした。

> Modori=SendMessage(hCombo,CB_GETEDITSEL,Hajime,Owari)
> などとしてみましたが、どちらも0で取得できませんでした。ヘルプが読みこなせない
> のですが、Hajime,Owariに取得できるのですか?もどり値の32ビット値を分解?
ActiveBasic付属のヘルプでは分からないのですけど、wParamとlParamにはポインタを指定します。

コード: 全て選択

SendMessage(hCombo,CB_GETEDITSEL,VarPtr(Hajime),VarPtr(Owari))
戻り値で取得する場合はLOWORD関数とHIWORD関数で戻り値を分解します。

コード: 全て選択

Modori=SendMessage(hCombo,CB_GETEDITSEL,NULL,NULL)
Hajime=LOWORD(Modori)
Owari=HIWORD(Modori)
> ポポイトおいていただいたソースこそお宝なのです。感謝
そういってもらえると助かります(^_^)
yama
記事: 58
登録日時: 2005年5月31日(火) 21:11
お住まい: 新潟市
連絡する:

Re: コンボボックスの編集で苦戦しています

#8 投稿記事 by yama »

いろいろお手数をおかけしましたが希望の動作を実現できました。
ありがとうございました。

> [code]SendMessage(hCombo,CB_GETEDITSEL,VarPtr(Hajime),VarPtr(Owari))
こちらではリリースコンパイル時に型変換の警告が出ました。
[警告] "SendMessage"の第4パラメータが、VoidPtrからLongに強制変換されています。
[警告] "SendMessage"の第3パラメータが、VoidPtrからDWordに強制変換されています。
動いてるから良いかといつも思いますが、修正の仕方がわからずそのままにしていますが、支障があるのでしょうか。

> 戻り値で取得する場合はLOWORD関数とHIWORD関数で戻り値を分解します。
> [code]Modori=SendMessage(hCombo,CB_GETEDITSEL,NULL,NULL)
> Hajime=LOWORD(Modori)
> Owari=HIWORD(Modori)[/code]

こちらは警告も無しで通しでした。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの編集で苦戦しています

#9 投稿記事 by 7 »

200回。
電源落とそうと最後に覗いたらいいタイミングですね。

> こちらではリリースコンパイル時に型変換の警告が出ました。
実際に動かしてなかったので忘れてました。

コード: 全て選択

SendMessage(hCombo,CB_GETEDITSEL,VarPtr(Hajime) As WPARAM,VarPtr(Owari) As LPARAM)
> 動いてるから良いかといつも思いますが、修正の仕方がわからずそのままにしていますが、支障があるのでしょうか。
型変換を行うには As演算子 を使います。

コード: 全て選択

Dim cnt As Long
Dim bStr[256] As Byte

	For cnt=0 To 25
		' Long型をByte型に変換
		bStr[cnt]=(Asc("A") + cnt) As Byte
	Next

	MessageBox(hMainWnd,bStr,"アルファベット",MB_OK)
支障といえば、データが壊れちゃうことがあるそうです。よく分かりませんけど...。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: コンボボックスの編集で苦戦しています

#10 投稿記事 by 淡幻星 »

横レス失礼します。
7さん さんが書きました:> 支障といえば、データが壊れちゃうことがあるそうです。よく分かりませんけど...。
こんなときのことです(と、私は理解しています)。

コード: 全て選択

Dim nLong As Long
Dim nByte As Byte

nLong = 843 '=&H34b = 0011,0100,1011(2進数)で12bitで表現される

nByte = nLong '←ここで強制変換の警告が出る
/* 【理由】
 Byte型であるnByte には8bitまでしか格納できない。
 とすると、
  上位の8bit「0011,0100」(=52=&H34)を格納すればよいのか、
  下位の8bit「0100,1011」(=75=&H4b)を格納すれば良いのか分からない。
 どちらにしろ、もともとの値(データ)である「843」とは違う値になってしまう。
 つまり、データが壊れる。
 ※普通は、下位のbitが格納されると思います。
*/

なので例えばこの場合は、格納されている数値が255(=&Hff)以下であれば、

コード: 全て選択

Dim nLong As Long
Dim nByte As Byte

nLong = 75 '=&H4b = 0100,1011(2進数)で8bitで表現される

nByte = nLong '←ここで強制変換の警告が出るが、問題は無い。
/* 【理由】
 もともと8bitまでしかデータが無い。
 そのまま8bit「0100,1011」(=75=&H4b)を格納するだけ。
 データは「75」のままであり、壊れない。
*/
となって、動作上は問題ないわけです。

警告が出るのは
「上に述べたように、データが壊れる可能性がありますが、良いんですか?」
って意味です。
As演算子を使うのは
「その可能性を分かった上で、壊れないデータ範囲を扱うので、
 型を変換しても問題ないんですよ。」
と明示するためです(と、私は理解しています)。

※都合上、4bit単位で区切って考えてます。
 もちろん、実際にはLong型は32bit(=4Byte)で表現されているので、
 「843」であれば「0000,0000,0000,0000,0000,0011,0100,1011」として
 格納されています。簡単のため、ゼロのみの部分は省略しました。



追伸:7さんへ。
200回記念、おめでとうございます♪(* ^o^)∠.:*:゚☆パン
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの編集で苦戦しています

#11 投稿記事 by 7 »

> こんなときのことです(と、私は理解しています)。
>

コード: 全て選択

Dim nLong As Long
> Dim nByte As Byte
> 
> nLong = 843 '=&H34b = 0011,0100,1011(2進数)で12bitで表現される
> 
> nByte = nLong '←ここで強制変換の警告が出る
> /* 【理由】
>  Byte型であるnByte には8bitまでしか格納できない。
>  とすると、
>   上位の8bit「0011,0100」(=52=&H34)を格納すればよいのか、
>   下位の8bit「0100,1011」(=75=&H4b)を格納すれば良いのか分からない。
>  どちらにしろ、もともとの値(データ)である「843」とは違う値になってしまう。
>  つまり、データが壊れる。
>  ※普通は、下位のbitが格納されると思います。
> */
>
> なので例えばこの場合は、格納されている数値が255(=&Hff)以下であれば、
>

コード: 全て選択

Dim nLong As Long
> Dim nByte As Byte
> 
> nLong = 75 '=&H4b = 0100,1011(2進数)で8bitで表現される
> 
> nByte = nLong '←ここで強制変換の警告が出るが、問題は無い。
> /* 【理由】
>  もともと8bitまでしかデータが無い。
>  そのまま8bit「0100,1011」(=75=&H4b)を格納するだけ。
>  データは「75」のままであり、壊れない。
> */
> となって、動作上は問題ないわけです。
>
> 警告が出るのは
> 「上に述べたように、データが壊れる可能性がありますが、良いんですか?」
> って意味です。
> As演算子を使うのは
> 「その可能性を分かった上で、壊れないデータ範囲を扱うので、
>  型を変換しても問題ないんですよ。」
> と明示するためです(と、私は理解しています)。
前から思ってたんですけど、結局入るデータは変わらないんですよね?As演算子使っても。
そうすると使う意味がないような気がします。
型が違う物どうしの演算とか代入だってことは明示的になりますけど。
あと、上位8ビットを格納するのか下位8ビットを格納するのか、っていうので思ったんですけど、型変換に上位を格納するのか下位を格納するのか指定するようなことができれば使う意味があると思いました。
あ。上位下位はよく考えたらビット演算すればよさそうですね。

というか型変換ってビット演算で出来てるんでしょうかね。

コード: 全て選択

Dim b As Byte

b=1023 As Byte	' 255が格納
b=(1023 And &FF)	' 255が格納
三日ぐらい前にC++の型変換で面白いコードがあってそれを見た時、型変換ってこんな使い方があるんだっ!って思ったんですけど、ActiveBasicじゃ動かなかったんですよね。
その時余計に型変換の存在意義が分からなくなりました...。
型変換の使い方じゃないって意味では動かない方がいいのかもしれませんけど。
どんな使い方だったかもう忘れちゃったんですけど、「i=(DWORD)*(DWORD)」みたいなコードだったような...。

> 200回記念、おめでとうございます♪(* ^o^)∠.:*:゚☆パン
ありがとうございます(^_^)
詰まらないことですけど、最近数値が綺麗に揃うとむしょうに嬉しくなってしまいます。
てふろん
記事: 3
登録日時: 2005年11月01日(火) 20:08

Re: コンボボックスの編集で苦戦しています

#12 投稿記事 by てふろん »

こんにちは、てふろんです。
もともとの質問とは違いますが、ちょっと気になったのでレスします。

全文引用だと長いので一部だけ取り出しての引用にさせていただきました。

> 前から思ってたんですけど、結局入るデータは変わらないんですよね?As演算子使っても。
> というか型変換ってビット演算で出来てるんでしょうかね。

As演算子と論理演算子では結果は違うと思いますよ。

コード: 全て選択


Dim a As Long
a = ( -1 As Byte )
a = ( -1 As Char )
上はたしかに&HFFを論理積した値と同じになりますが、
下はリテラル値と同じ-1を指しています。
Byteにおける&HFFは255ですが、Charにおける&HFFは-1です。
これがバイトに切り出しているだけなら同じ255にならないといけないです。

ですので、きちんと型を変換したのち、
Char→Longへの上位変換されていると思います。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

Re: コンボボックスの編集で苦戦しています

#13 投稿記事 by 淡幻星 »

ひきつづき、質問内容と違う横スレですが、失礼します。
> 前から思ってたんですけど、結局入るデータは変わらないんですよね?As演算子使っても。
> そうすると使う意味がないような気がします。
> 型が違う物どうしの演算とか代入だってことは明示的になりますけど。
基本的には「明示的にする」以外の意味は無いと思っています。
故に「エラー」ではなく、「警告」なのだと。
私は、普段は無視してますから^^;<型変換の警告

・・・例えばC++だったら、

コード: 全て選択

int a,b;
double d;

a = 5;b=2;

d = a / b // 整数演算として扱われ2.0が格納される。
d = (double)a / b // 浮動小数点演算として扱われ、2.5が格納される。
というように、明示的変換以外の用途もあるんですが。
ABだと、どっちも「2.5」が格納されますね^^;

>上位下位はよく考えたらビット演算すればよさそうですね。
です。

>というか型変換ってビット演算で出来てるんでしょうかね。
みたいです。

コード: 全て選択

Dim b As Byte
Dim n As Long

n = 843
b = n As Byte '下位8bitの「75」が格納される。
b = n '同様に「75」が格納される。
> その時余計に型変換の存在意義が分からなくなりました...。
そういえば、今思い出しました。
こんなときに意味があるかと。

コード: 全て選択

Dim w As Word
Dim i As Integer

i = &Hffff '「-1」を表す。
w = i As Word '「65535」を表す。
すっかり忘れてました(^^;)。


---
投稿が前後してしまったようです(^^;) 以下、追記です。
えっと、てふろんさんが仰っている通りです。
型変換(キャスト)と、ビット演算では代入結果は必ずしも同じになりません。
(普段、キャストを使う場面では「正の整数」ばかりを扱っているので、すっかり忘れていました。)
ちなみに、Byte型とChar型を例に取れば、
・Byte型→ビットそのままに、2進法を10進法に変換。
・Char型→最上位ビットはマイナス(&H80=-128)として扱う。それ以外のビットはプラスで扱い、2進数を10進数に変換。
です。・・・って、これはすでにご存知かもしれないですね^^;
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの編集で苦戦しています

#14 投稿記事 by 7 »

てふろんさん さんが書きました:As演算子と論理演算子では結果は違うと思いますよ。

上はたしかに&HFFを論理積した値と同じになりますが、
下はリテラル値と同じ-1を指しています。

ですので、きちんと型を変換したのち、
Char→Longへの上位変換されていると思います。
なるほど。ビット演算とはちょっと違うんですね

使ったことの無いChar型についてちょっと調べてみたら、ASCIIコードだけを扱うんですね。
-128~127なので、マイナスの文字コードがあってそれを操作する為の型なのかと思ってました...。
淡幻星さん さんが書きました:Code:
Dim w As Word
Dim i As Integer

i = &Hffff '「-1」を表す。
w = i As Word '「65535」を表す。
値が溢れた場合?、上限値(?)が設定されるんですね。これは何か使い道がありそう。
淡幻星さん さんが書きました:ちなみに、Byte型とChar型を例に取れば、
・Byte型→ビットそのままに、2進法を10進法に変換。
・Char型→最上位ビットはマイナス(&H80=-128)として扱う。それ以外のビットはプラスで扱い、2進数を10進数に変換。
です。・・・って、これはすでにご存知かもしれないですね^^;
いや、ご存知じゃないです...どうやるんでしょう。説明をうまく理解できません...。
てふろん
記事: 3
登録日時: 2005年11月01日(火) 20:08

Re: コンボボックスの編集で苦戦しています

#15 投稿記事 by てふろん »

またまた、てふろんです。
まぁ、私の言ってることは揚げ足とりなので、あんまり気にしないで下さい。

Char → Long の上位変換を論理演算で表現しようとするとこんな感じなのかな?

コード: 全て選択

Dim a As Long
Dim b As Char
b = -2
a = &HFFFFFFFF Xor Not b
*追記
上でいけるかと思いましたが、
Not b の結果がLong型になってないと成立しない計算ですね。

テストでは成功したので、書きこみしたのですが、
Not b の結果はChar型なんだけど、それをまた上位変換させてるだけですね。
なんかお馬鹿な書きこみしてすみませんでした。
返信する