ページ 1 / 2
コンボボックスの編集で苦戦しています
Posted: 2006年5月10日(水) 18:50
by yama
いつも勉強させていただいています。またお教えいただきたいのですが。
使用したいのはデフォルトタイプのComboBoxです
'comboにデーターを読み込む
'comboの指定行を選択状態にする
'何行目が選択されているかを取得
など基本的な部分はパワーユーザーなどのホームページを参考に何とか動く様になりました。リスト部分のある行をクリックすると、エディットボックス部分に全選択状態で入りますが、うまく動かないところは、エディットボックス部分の編集時で
1.初期化時に入力した文字列を一部削除するとエディットボックスが見た目空になってしまい続けて入力ができません。編集は正しく行なわれておりリスト部には正しく表示されます。リストの該当行を再度クリックするとまた全選択で表示はされます。
2.初期化時に入力した文字列に追加挿入しようとすると1文字は入るが2文字目に「未知の文字列が解放されようとしました。」となってしまいます。
3.コントロールの幅以上には編集の入力ができないのは仕様でしょうか?
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]
Sub MainWnd_ComboBox1_EditChange()
'ComboBox1の変更を取り出しグローバル変数にセット
Dim str[256] As Byte
Dim length As Long
SetWord(str, 256)
'選択番目の文字列を取得
length=SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_GETLBTEXT,Nangyoume,str)
str[length]=NULL
'題名をグローバル変数にセット
GetWindowText(GetDlgItem(hMainWnd,ComboBox1),str,255)
s_ToName[Nangyoume]=MakeStr(str)
SetCombo()
'編集している行を選択状態にする
SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_SETCURSEL,Nangyoume,0)
End Sub
数年前も組み込みに挑戦しましたが挫折していて、再挑戦しましたが又つまづいております。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月11日(木) 01:51
by 7
> 3.コントロールの幅以上には編集の入力ができないのは仕様でしょうか?
これはコンボボックスのプロパティ「水平オート スクロール」にチェックを入れます。簡単ですね。
> 1.初期化時に入力した文字列を一部削除するとエディットボックスが見た目空になってしまい続けて入力ができません。編集は正しく行なわれておりリスト部には正しく表示されます。リストの該当行を再度クリックするとまた全選択で表示はされます。
> 2.初期化時に入力した文字列に追加挿入しようとすると1文字は入るが2文字目に「未知の文字列が解放されようとしました。」となってしまいます。
「初期化時」っていうのはクリエイト時のことでしょうか?
よく分からなくて、その状況を再現できずにいます...もっと詳しく書いて頂ければと思います。
解決にはならないんですけど、GetDlgItem()関数を多用するなら変数に保管するといいですよ。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
' ComboBox1の変更を取り出しグローバル変数にセット
Sub MainWnd_ComboBox1_EditChange()
Dim hCombo As HWND
Dim str[256] As Byte
hCombo=GetDlgItem(hMainWnd,ComboBox1)
' 要らないのでは?
SetWord(str,256)
' 選択番目の文字列を取得
str[SendMessage(hCombo,CB_GETLBTEXT,Nangyoume,str)]=NULL
' 題名をグローバル変数にセット
GetWindowText(hCombo,str,255) ' str が潰れる
s_ToName[Nangyoume]=MakeStr(str)
SetCombo()
' 編集している行を選択状態にする
SendMessage(hCombo,CB_SETCURSEL,Nangyoume,0)
End Sub
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月11日(木) 08:17
by ゲスト
> > 3.コントロールの幅以上には編集の入力ができないのは仕様でしょうか?
> これはコンボボックスのプロパティ「水平オート スクロール」にチェックを入れます。簡単ですね。
これは目からうろこ、さんかくマークがつくのだと思ってました。
> よく分からなくて、その状況を再現できずにいます...もっと詳しく書いて頂ければと思います。
実行できるコードまとめてみます。それをまたみていただけますか?言葉では
伝えるのが難しい。
> 解決にはならないんですけど、GetDlgItem()関数を多用するなら変数に保管するといいですよ。
たしかに非常に見易いですね。さっそく取り入れさせてぃただきます。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月11日(木) 11:59
by yama
上のメッセージ、ログインしてませんでした。
> > 1.初期化時に入力した文字列
は端に選択されエディットボックスに表示された文字列で、初期化<=立ち上げ時に文字配列へ文字をセットすることを意図してました。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
DIM Nangyoume As Long 'comboの何行目かを格納
DIM s_ToName[4] As String
s_ToName[0]="1共通"
s_ToName[1]="2現場"
s_ToName[2]="3一般"
s_ToName[3]="4仮設"
s_ToName[4]="5管理"
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
'comboにデーターを読み込む
SetCombo()
'comboの0行を選択状態にする
SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_SETCURSEL,0,0)
End Sub
Sub MainWnd_ComboBox1_SelChange()
'何行目が選択されているのを"Nangyoume"に取得
Nangyoume=SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_GETCURSEL,0,0)
'編集している行を選択状態にする
SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_SETCURSEL,Nangyoume,0)
End Sub
Sub MainWnd_ComboBox1_EditChange()
Dim hCombo As HWND
Dim str[256] As Byte
hCombo=GetDlgItem(hMainWnd,ComboBox1)
' 選択番目の文字列を取得
str[SendMessage(hCombo,CB_GETLBTEXT,Nangyoume,str)]=NULL
' 題名をグローバル変数にセット
GetWindowText(hCombo,str,255) ' str が潰れる
s_ToName[Nangyoume]=MakeStr(str)
SetCombo()
' 編集している行を選択状態にする
' SendMessage(hCombo,CB_SETCURSEL,Nangyoume,0)
End Sub
Sub SetCombo()
'コンボボックスを空に
SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_RESETCONTENT,0,0)
'コンボボックスに文字列を追加
Dim FW As integer
For FW = 0 To 4
SendMessage(GetDlgItem(hMainWnd,ComboBox1),CB_ADDSTRING,0,s_ToName[FW])
Next FW
End Sub
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月11日(木) 13:28
by 7
ちょっとコード変えちゃいました。
エラーが起きた時のことは考慮してません [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
' コンボボックスのエディット部分のカーソル位置を設定
Function ComboBox_SetEditSel(ByVal hWnd As HWND,ByVal iStart As Integer,ByVal iEnd As Integer) As Long
ComboBox_SetEditSel=SendMessage(hWnd,CB_SETEDITSEL,NULL,MAKELONG(iStart,iEnd)) As Long
End Function
' コンボボックスに項目を挿入
Function ComboBox_InsertString(ByVal hWnd As HWND,ByVal nIndex As Long,ByVal lpString As BytePtr) As Long
ComboBox_InsertString=SendMessage(hWnd,CB_INSERTSTRING,nIndex As WPARAM,lpString As LPARAM) As Long
End Function
' コンボボックスの項目を削除
Function ComboBox_DeleteString(ByVal hWnd As HWND,ByVal nIndex As Long) As Long
ComboBox_DeleteString=SendMessage(hWnd,CB_DELETESTRING,nIndex As WPARAM,NULL)
End Function
' コンボボックスの項目を選択
Function ComboBox_SetCurSel(ByVal hWnd As HWND,ByVal nIndex As Long) As Long
ComboBox_SetCurSel=SendMessage(hWnd,CB_SETCURSEL,nIndex As WPARAM,NULL)
End Function
Dim hCombo As HWND ' コンボボックスのハンドルを持つ
Dim Nangyoume As Long ' 選択されている項目のインデックスを持つ
Dim s_ToName[4] As String
s_ToName[0]="1共通"
s_ToName[1]="2現場"
s_ToName[2]="3一般"
s_ToName[3]="4仮設"
s_ToName[4]="5管理"
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
' ウィンドウが作られた時
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
Dim cnt As Integer
' コンボボックスのハンドルを取得
hCombo=GetDlgItem(hMainWnd,ComboBox1)
' コンボボックスの項目を設定
For cnt = 0 To 4
SendMessage(hCombo,CB_ADDSTRING,0,s_ToName[cnt])
Next
' 最初の項目を選択
ComboBox_SetCurSel(hCombo,0)
End Sub
' コンボボックスの選択されている項目が変更された時
Sub MainWnd_ComboBox1_SelChange()
' 選択されている項目のインデックスを取得
Nangyoume=SendMessage(hCombo,CB_GETCURSEL,0,0)
End Sub
' エディット部分の内容が変更された時
Sub MainWnd_ComboBox1_EditChange()
' エディット部分に入力された文字列を取得
s_ToName[Nangyoume]=ZeroString(256)
GetWindowText(hCombo,s_ToName[Nangyoume],255)
' 選択されている項目を削除し、新しい項目を挿入
ComboBox_DeleteString(hCombo,Nangyoume)
ComboBox_SetCurSel(hCombo,
ComboBox_InsertString(hCombo,Nangyoume,s_ToName[Nangyoume]))
' エディット部分の最後尾にカーソルを設定
ComboBox_SetEditSel(hCombo,Len(s_ToName[Nangyoume]) As Integer,-1)
End Sub
SetCombo()関数は要らないと思ったので消しました。他に使い回すなら消さなくてもいいです。
あと、hComboをグローバルにしました。大したことのないコントロールなら毎回取得してもいいんですけど、コンボボックスが大事なコントロールなのかと思ったので...。
ポイポイっとソースを置いていくのは簡単だけど、説明するのって難しい...。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月11日(木) 18:04
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で検索をかけてみましたがかなりディープなのか日本語ページもすくなくて
しょぼん状態です。
> ポイポイっとソースを置いていくのは簡単だけど、説明するのって難しい...。
ポポイトおいていただいたソースこそお宝なのです。感謝
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月11日(木) 22:32
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)
> ポポイトおいていただいたソースこそお宝なのです。感謝
そういってもらえると助かります(^_^)
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 09:39
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]
こちらは警告も無しで通しでした。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 09:58
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)
支障といえば、データが壊れちゃうことがあるそうです。よく分かりませんけど...。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 19:21
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^)∠.:*:゚☆パン
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 20:29
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^)∠.:*:゚☆パン
ありがとうございます(^_^)
詰まらないことですけど、最近数値が綺麗に揃うとむしょうに嬉しくなってしまいます。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 21:24
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への上位変換されていると思います。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 21:38
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進数に変換。
です。・・・って、これはすでにご存知かもしれないですね^^;
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 22:30
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進数に変換。
です。・・・って、これはすでにご存知かもしれないですね^^;
いや、ご存知じゃないです...どうやるんでしょう。説明をうまく理解できません...。
Re: コンボボックスの編集で苦戦しています
Posted: 2006年5月12日(金) 23:00
by てふろん
またまた、てふろんです。
まぁ、私の言ってることは揚げ足とりなので、あんまり気にしないで下さい。
Char → Long の上位変換を論理演算で表現しようとするとこんな感じなのかな?
コード: 全て選択
Dim a As Long
Dim b As Char
b = -2
a = &HFFFFFFFF Xor Not b
*追記
上でいけるかと思いましたが、
Not b の結果がLong型になってないと成立しない計算ですね。
テストでは成功したので、書きこみしたのですが、
Not b の結果はChar型なんだけど、それをまた上位変換させてるだけですね。
なんかお馬鹿な書きこみしてすみませんでした。