戻る 2024/09/16 10:33:09
文字化けの概念
VB2.0では、UNICODEのようなものは存在していなかったので問題はなかったが、VB4.0ではUNICODEが内部で採用されているので、注意が必要になる。
Lenb(“あいう”)は、6
Len(“あいう”)は、3
Lenb(“あい1”)は、6
Len(“あい1”)は、3
である。UNICODEは半角文字も全角文字も、1文字を現わすのに2バイト必要である。
Line Input #1, TextLine
これは、改行までを、 TextLineに読み込むステートメントである。
しかしTextLineはstring型等の単項目である必要がある。半角と全角が混在する場合、
TextLineをユーザー定義型を利用して複数項目に分解するのは困難である。
Open "TESTFILE" For Random As #1 Len = Len(MyRecord)
Get #1, Position, MyRecord
これは、Lenで指定されたバイト数分、 ユーザー定義体MyRecordに読み込みを行う。 ユーザー定義体の中に固定長文字列が入っていた場合は、ANSI換算のバイト区切りで、ユーザー定義体のメンバーに正しく読み込まれる。
Type Record
ADD As String * 8
Name As String * 8
End Type
ファイル内容 あいう@@12345678
上記を読み込むと
ADD = あいう@@...
Name = 12345678
と正しく読み込まれる。
書き込みも、逆に行われるだけで、正しくセットされる。
put/getは改行の概念がない。openするときのlengthが単位となる。
汎用機と同様な改行を付加する場合は、書き込むときにchr$(13)+
chr$(10)=CRLFを最後にデータの一部としてセットする必要がある。
エディター等でこのファイルにパッチを当てるとき、エディターの種類によっては改行コードをCRLFまたはCRのどちらか不定のことがあるので注意する必要がある。
ファイルのIOの方法2種
VBには、ファイルのアクセス方法として良く使用するものが2通りある。一つは改行記号までを1レコードとしてあつかう、可変長に向くタイプ。もうひとつは、構造体を利用して読み込むタイプであり、漢字・ANKが混在しても位置がづれない。1997/10/22
固定長タイプ
Open "MotoFile" For Random As 1 Len = 256
Open "SakiFile" For Random As 2 Len = 256
'レコード数を調べる
RecordCount=LOF(1) \ 256
'読み込み
Get #1, Index , usr_IO_Rec
GETしたあと、読み込めなかった時は、EOF()がTrueになる
'書き込み
Put #2, Index, usr_IO_Rec
CloseINDEXは、1スタート
可変長タイプ
Open "MotoFile" For Input As 1
Open "SakiFile" For Output As 2
'読み込み
Line Input #1, str_IO
Line Inputしたあと、最後の有効レコードの時、EOF()がTrueになる
'書き込み
Print #2, str_IO
Close
デザイン時のプロパティーでIMEMODEを設定しても、gotFoucusイベントにより、勝手に変更されてしまう。これを防ぐために下記のように強制的にをIMEMODEをセットするしかない。
comboobject.imemode = vbIMEDisable (使用禁止にする)
Dim wk_single as single
wk_single = 3.1
debug.print wk_single
これを見ると、3.100001234などのゴミが残っている。これを計算にそのまま使うと、誤差が出る。Single型は使用しないほうが懸命であり、Double型で代用すべきである。
インデックスの0004も参照。
コマンドボタンをVisble Falseにした後で、なぜかコントロールBOXがアクティブになってしまった。
(草川担当 一覧表画面にて。対応策は、フォームのコントロールBOXをFalseにした。)
integerどうしのかけわりの結果で、小数点付きの場合でも、答えはSingle型相当の制度しかでない。より正確に計算したい場合は、キャストする必要がある。
INIファイルの大きさは、64Kbyteまでである。それ以上は、APIで読み込めない。 97/05/31
Val関数の戻り値は、どんな時でも必ず数値を返す。(Null値はNullを返す)ただし、カンマ、ブランク、数字以外の文字が入っているときは、その直前までしか返さない。
ごくまれに、小数を含まない数値(doubleでも)をFixすると、値が狂う時がある。原因不明。
→浮動小数点をfixするとなるケースがある。single型の3は2.99999.......かもしなないから。
ユーザー定義型を、関数の引数に使用するとき、BYREFは使用できない!。
動的配列を引数に使用することは可能である。
dim aaa() as integer
Call subroutine(aaa)
97/10/13
FrmモジュールにPublicの関数を宣言するとき、その引数にはPublicのユーザー定義型を使用することができない。コンパイルエラーになる。
(VB4)
FrmモジュールにPublicの関数は、ダメだけど、
Friendの関数にすれば、okだった!
(VB6 2003/01/17)
フォームをモーダル表示すべく、Show 1 を使用した場合、ダイアログがアンロードされるか、非表示されるまで、次のstepに進まない。
マイクロソフトの思想を想像すると、タスクバーには、アプリケーションの種類を表示するものと思われる。であるから、SDKを見てもツールウィンドーはダイアログフォームはタスクバーには表示しずらいもののようだ。実際、ShowinTaskBar=Trueにしても Show vbModalにすると、タスクバーには出せない。
アプリケーションの作りは、メインフォームだけは、モードレスフォームにするのが正しいロジックなのかもしれない。
http://www.mtakahashi.com/old/a4625.html
http://www.alpha-net.ne.jp/users2/uk413/vc/VCT_TaskTray.html
2002/02/26
Keydownイベントで、Send{"TAB"}を使用するのが一番簡単だが、漢字入力のテキストボックスのためにIME
ModeをONにしようとしても、Send{"TAB"}を使用した場合うまくいかないことがあった。
原因不明。解決方法はSetFocusしかない。
VBAによるOLE通信機能を使用すれば、VBでEXCELをフルコントロール可能である。
しかし、doeventsを適宜入れないと、VB側の処理がうまく行われないときがあった。
OLEによるプロセス間通信は、遅くて耐えられない。早い順に、VB内部コード>EXCEL内部マクロ>OLE通信
の順である。VBとEXCELの間の通信は極力避けたほうが良い。
通常はロストフォーカスで、BのEnabled Falseを行うが、隣接している場合はこの方法がつかえない。TABを押した時点でBにフォーカスが移動しているからである。よって下記の方法をとる。
A.Cheng events
if A.text = NG then
B.tabstop = false
else
B.tabstop = true
B.enabled = true
endif
A.lostfocus events
if A.text = NG then
B.text = ""
B.enabled = false
else
B.enabled = true
endif
windowsで[ALT]+[TAB]で表示される候補は、タスクバーに並んでいるものである。その表示名は、フォームのキャプションである。
タスクリストに表示されるものも、タスクバーに並んでいるものである。
SSパネルをクリックすると、フォーカスがSSパネルに移る。しかしGOTフォーカスイベントは存在しない。IMEのON・OFFを制御するフォームに於いて、パネルをクリックすると、パネルがフォーカスを持っている間、IMEモードはwindows依存になる。勝手にONになることもあるので注意。
API関数を使用してフォームのhWNDをもとにIMEOFFにする方法が有るかもしれない。
97/08/19
上記のテキストボックスでkeyDownイベントを使用する場合、下記のキーは正しく制御できない。
とりあえず、発見したもの。
97/08/20
この関数は、初回に引数をセットし、2回目に引数なしでCALLすると次々とファイル名が取得できるが、その間に下位関数等でDir関数を使用していると期待どうりの動きをしない。loopのなかのloopも使用できないので注意。
97/10/13
ユーザー定義型どうしの転送に良く使うが、下記の構造のユーザー定義型はLSETできず、コンパイルエラーになる。
Type t_a
k1 as string *1
end Type
Type t_b
k1 as t_a
end Type
Type t_c
k1 as t_a
end Type
dim b as t_b
dim c as t_c
Lset c = b
ユーザー定義型の配列を持つユーザー定義型は使用できない
97/11/04
ユーザー定義型の配列を持つユーザー定義型についての、解決方法発見。
lsetでは無理であるが、API関数CopyMemoryを使用すれば、簡単に実現できる。1999/08/03
カレントディレクトリではなく、当EXEファイルの存在ディレクトリが取得できる。
97/11/07
起動元EXEで、起動先EXEを起動した後、起動元EXEのロジックでSETFOCUSを行うと起動元フォームがアクティブになってしまう。起動元のSETFOCUSが先に走り、後で起動先の画面がSHOWされればこの現象は起きない。しかしタイミングの問題で保証性がない。
不完全な回避方法は、起動先EXEのフォームロードイベントの最後に、DOEVENTSを行うことにより、起動元のSETFOCUSを完了させてしまう事である。
98/01/28
shell 関数などで起動exeを相対パスで指定する時に、自分のフォルダーを基準に考えると、うまくいかないことがある。原因は、相対パスはあくまでカレントパスの相対だからである。自分のフォルダー(app.path)は、必ずカレントパスになっている保証はない。
完全な解決方法はapp.path & "\" & [相対パス]で指定することである。事実上絶対パス指定になる。
98/04/15
インプロセスOLEサーバーの作り方
クラインと側の呼び出し例
Dim 項目As New 識別子.クラス名
call 項目.メソッド名
インプロセスOLEサーバーのモーダルフォームについての補足。
インプロセスOLEサーバー内でフォームを表示するときは、モーダルフォームしか使用できない。(仕様)
VBPでテスト中は、クライアントに対して別のVBのプロセス、つまりアウトプロセスで動いているので必ずしもクライアントに対してモーダルにならない。が、DLLにしてからはクライアントに対してモーダル表示になる。
インプロセスOLEサーバー(a)から、インプロセスOLEサーバー(b)の呼び出しは可能である。このとき、(a)のクライアントは、(b)を参照設定しておく必要がない。
ディフォルトは、EXEと同じディレクトリになっている。
$(AppPath)
たとえば、<EXEDIR>\DATA\に入れたい時は、
$(AppPath)\DATA
と指定すれば良い。
1997/10/24
以下の方法で、手動でdll / ocxを登録できる。
REGSVR32.EXE XXXX.DLL
削除の方法は
REGSVR32.EXE /u XXXX.DLL
VBどうしでDDEの通信をするときの方法。
〜.LinkTopic = 相手のApp.Title | 相手のLinkTopic である。
対策方法
エクスプローラなどから、ファイルの関連づけを変更する。
"c:\program files \DevStdio\vb\vb5.exe" "%1"
のように、EXE名を"で囲む。 1998/06/08
コーディング上で、BEEPと記述してたときの音は、コントロールパネルのサウンドの"一般の警告音"に設定されている音が鳴る。
サウンドドライバーがインストールされていないマシンでは、自動的に本体のBEEP音がなるが、サウンドドライバーがインストールされているマシンでは、注意。1997/12/07
エクスプローラー上の名前が"TestExe.exe"であっても、SHELL
"TESTEXE.EXE"とした場合、App.Exenameは"TESTEXE"になる。
1998/05/12
1998/12/25
一般に、Enabled=Falseのコントロールは、クリックイベントを受け付けないが、Enabled=Falseにしたイベント処理が終わっていないときは、イベントを受け付けてしまう。完全に防ぐためには例えばスクリーンオブジェクトのマウスカーソルイベントが砂時計のときは、クリックイベントを抜けるような対策を練る事である。
1998/12/27
Dim L_Control As Control 'フォーム上のコントロール操作に使用
'**** 各種コントロールを初期化する
For Each L_Control In Me
Select Case TypeName(L_Control)
Case "TextBox", "ImText"
'コントロールのテキストをブランククリアする。
'バックカラーをノーマルに戻す
L_Control.Text = ""
L_Control.BackColor = CC_ColorBack
Case "ImDate"
'日付コントロールのテキストを初期化する。
'バックカラーをノーマルに戻す
L_Control.Number = 0
L_Control.BackColor = CC_ColorBack
End Select
Next L_Control
VBには、いくつかのNULLに関する定数がある。それぞれ以下のような意味である。
1999/07/05 山口の自習より
VBに標準でついている、タブダイアログコントロール(SSTAB)上にフレームを置いたとき、LOADイベント中でENDしてもうまくいかない。ENDせず不安定な状態で処理が続行できてしまう。
1999/07/29
CreatObjegt を行い、 Object.Visible = false とすれば、ExcelやWordは全く見えなくなるが、Accessはタスクバーにアイコンがみえてしまう。マイクロソフトによれば、これは仕様との事。
Office97 98/03/04
厳密な計算を要求される金額計算などのロジックを使う時は、ご一読。
マイクロソフトサポート技術情報 [VB4] データ型と演算誤差についての注意 : J029974
1999/09/21
メニューバーのあるフォームの初期表示位置は、StarupPositionの設定ができない。
よって、Loadイベントなどで、コーディングする必要がある。
例)
Me.Left = (Screen.Width - Me.Width) / 2
Me.Top = (Screen.Height - Me.Height) / 2
1999/09/21
[Ctrl] + [Break] で、止まります。
1999/11/25 B.O.C. より
テキストボックスなどを上下に配置したときにピッチ(桁位置)を揃えるためには、次のフォントを使用のこと。
MSゴシック/MS明朝 9ポ or
12ポ (これ以外の大きさでは揃いません)
Terminal
System
2000/04/15 伊東君の投稿を元にしました。
2003/10/29 時点では、揃っている!WindowsXPでは、揃うように改善されているのか......?
↑WindowsXPではフォントピッチの扱いが変更されています。
MSDN :Windows XP での全角固定ピッチフォントの仕様変更 を参照
2004/05/21
自分で作ったクラスには、ユーザーイベントを実装することができる。VB5〜 それの実装例をしめす
Project1.vbp
form1を作成し、コマンドボタンCommand1と、テキストボックスText1を配置。
以下のコードを貼り付ける。
'Class1を、イベント付きクラス名として、clsTestを定義
Dim WithEvents clsTest As Class1
Private Sub clsTest_eventCommand1()
Text1.Text = "eventCommand1"
End Sub
Private Sub clsTest_eventCommand2()
Text1.Text = "eventCommand2"
End Sub
Private Sub clsTest_eventStarted(starttime As Date)
Text1.Text = "eventStarted " & Format(starttime, "hh:mm:ss")
End Sub
Private Sub Command1_Click()
Set clsTest = New Class1
clsTest.main
End Sub
インベント付きのクラスを作成する。
ライブラリー名:cClass1 (プロジェクトのオブジェクト名に相当)
クラス名:Class1
'クラスの外部公開用のユーザーイベントの宣言 Public Event eventStarted(starttime As Date) Public Event eventCommand1() Public Event eventCommand2() Public Sub main() 'クラスの利用者に対して、スタートされた事を通知する RaiseEvent eventStarted(Now) 'form1に対して、クラスのメソッドを呼び出すことが 'できるように、自分自身のインスタンスを与える 'C++のthis pinter を渡すのと同じ意味 Set Form1.cClass1 = Me Form1.Show End Sub ' 'Friendは、このプロジェクト内でのみ有効なスコープ 'インスタンスの利用者からは見えない ' Friend Sub subCommand1() 'イベントを発生させる 'RaiseEventは、クラスモジュールでしか、使えないようだ RaiseEvent eventCommand1 End Sub ' 'Friendは、このプロジェクト内でのみ有効なスコープ 'インスタンスの利用者からは見えない ' Friend Sub subCommand2() 'イベントを発生させる RaiseEvent eventCommand2 End Sub |
form1を作成し、コマンドボタンCommand1とCommand2を配置。
以下のコードを貼り付ける。
Private Sub Command1_Click() 'クラスのインスタンスのメソッドを呼び出す Call cClass1.subCommand1 '本来なら 'RaiseEvent cClass1.eventCommand1 'のように直接イベントを呼び出したいが、 'できなかったので、メソッド経由にした。 End Sub Private Sub Command2_Click() 'クラスのインスタンスのメソッドを呼び出す Call cClass1.subCommand2 End Sub |
クラス側では、クラスモジュール以外では、RaiseEvent を呼び出せないので注意。上記の例では、クラスへのポインタ変数を利用したメソッド呼出を行い、その中で、RaiseEventを使用している。
2001/06/25
こんなメッセージが出た
ID 文字列が長すぎます: '項目'
ActiveX コンポーネントの ProgID は、39 文字以内の文字列でなければなりません。ProgID は、プロジェクト名とクラス モジュール名を連結して作成されます
命名時には注意ですねー
2003/05/02
2002/07/09
フォーム単純にshowすると、まるでコンスタントオブジェクトのごとく振る舞う。つまり
クラス名.メソッド
の動きになる。よってフォームの名前(VBで言うところのオブジェクト名)さえ分かっていればアプリケーションのどこからでもアクセスする事が可能になる。
また、アプリケーション内で必ず1つしか実体が存在しない事が保証できる。
一方クラスとインスタンスを完全に分ける実装も可能である。
Dim form1 As Form
Set form1 = New frmSpotKensyouMain
form1.Show
これは、インスタンスを幾つも作ることが可能になるので、同一種類のフォームを幾つも表示する事が可能になる。
フォームのInitializeイベントは、インスタンスを生成した時に発生するとヘルプにある。
Set〜New を行ってフォームをハンドリングした場合は、期待通りのイベントが発生するが、
スタティクで運用した場合は、一番最初に呼び出した時だけ発生する。
ただし
Set クラス名 = Nothing
とすれば、スタティックといえども、破棄されると思われる。(再度呼び出すとInitializeイベントが発生するこから)
「クラス名.メソッド」で運用する場合、Initializeイベントでコントロールの初期化を行なう場合は要注意。
アンロードすると、フォーム上のコントロールの値は消えてしまう。再度ロードを行った時は、デザイン時のプロパティで初期化されている。
VBの設計思想がよく判らないが、クラス単位にフォームインスタンスを保持できるポインタがある雰囲気かもしれない。Initializeイベントはそのポインタに実体をアロケートした時のCALLBACK関数と考えれば、合点がいく。
参考資料
マイクロソフト サポート技術情報 - JP147665
http://support.microsoft.com/default.aspx
http://www.microsoft.com/japan/support/kb/articles/JP147/6/65.asp
2002/07/17
大変参考になる記事を見つけた
http://www.gj.il24.net/~nakasima/vb/tech/end/index.htm
2002/07/31
C:\Program Files\Microsoft Visual Studio\VB98\Template配下の各フォルダに自分で作ったやつを放り込んでおくだけで、新規作成ダイアログの中にも登場させる事ができるようになります。
けど、テンプレートを修正したからといって、既存のものが修正されるわけでもなく、あんまり有効利用が出来そうにないようにも思えます。
2002/07/22
ちょと使ってないと、すぐ忘れるんですね〜。
けど、ほとんど、メニューバーに説明が乗っていますから、それを見ながら思い出しましょう。
ショートカットキー | 内容 | |
Ctrl + R | プロジェクトウィンドウを表示 | |
Ctrl + Shift + F2 | コードの元の位置に移動することができます。コードを編集しているか、[プロシージャの定義] コマンド呼び出しを行っていて、コード ウィンドウが表示されているときのみ有効です。最後にアクセスされた行または編集された行が 8 つまで、記録されています。デザイン時 および中断モードでのみ使用できます。 | |
F8 | いきなりステップ実行 | |
Ctrl + Break | 実行処理の強制停止 |
2002/08/28
自分でNewしたインスタンス変数に Set Nothing しても、インスタンス変数そのものはnullになるけど、実体は生き続けている時がある。他の変数が、実体を保持している時だ。
Javaと同様、どこからも参照されなくなった時点で、消滅するみたい。
Dim wk As Class1
Dim kp1 As Class1
Set wk = New Class1 'ここでアロケートされる
Set kp1 = wk '参照をコピー
Set wk = Nothing 'wkはnullになる
Me.Print kp1.Property '動く
Set kp1 = Nothing 'ここで、消滅する
注意点は、VBのガベージコレクションは、参照する変数が無くなった時点で必ずスグ解放する事らしい。
.NETのVBでは、JAVAと同じく、解放タイミングは不定だそうです。
http://www.microsoft.com/japan/msdn/net/vbtransitionguide/chapter2/chapter2_5.asp
2002/08/09
変数名だけでは、できません。
フレーム、イメージボックスなど、コンテナに載せないとできません。
VB6 2002/09/11
文字列変数のアドレス取得関数
StrPtr()
データ型変数のアドレス取得関数
VarPtr()
オブジェクト変数のアドレス取得関数
ObjPtr()
2002/10/08
Visual Basicの配列の実体はSAFEARRAYであり、次元や要素数とデータを指すポインタのフィールドを持つ構造体である。
http://www.ops.dti.ne.jp/~allergy/com/com.html
オートメーションを使って配列を渡すには、セーフ配列(へのポインタ)を含むバリアントを作成します。セーフ配列は単一のデータ型の一次元または二次元の配列です(しかしこの単一データ型は VARIANT でもよいため、型を複数含んだ配列も可能です)。Visual Basic では配列の下限は 0 でなくてもよいので、セーフ配列には下限とサイズも格納しなければなりません。
これらの配列がセーフ配列と呼ばれるのは、これらが範囲情報持ち、配列のデータにアクセスする前に添え字の範囲を確認できるからです(SafeArrayGetElement
と SafeArrayPutElement API
はこれを自動的に行います)。これに比べ、C と C++
配列の範囲検査が行われることはめったにないため、添え字の有効範囲を超えたことによる原因究明の難しい大きなエラーが起きやすいのです。
http://www.microsoft.com/japan/developer/library/dsmsdn/drgui042099.htm
2002/10/09
オプションボタンやコマンドボタンなど、フォーム上のコントロールを動的に増やすには LOAD命令を使えばできる。ただし、増やす元になるクラスが配列コントロールとして存在していないとダメ。
For ix = 1 To 3
’コマンドボタンインスタンスを生成する
Load cmdArray(ix)
’縦に並べる
cmdArray(ix).Top = cmdArray(ix).Top + ix * 300
'可視状態に変更する
cmdArray(ix).Visible = True
Next ix
これを応用すると、メニューバーの項目も動的に追加することができる。
For ix = 1 To 10 Load men_array(ix) men_array(ix).Caption = "メニュー項目" & ix Next ix
ということは、減らす時は、Unloadすれば良いわけですね。
http://www.ag.wakwak.com/~kagawa/vbtipmenu.htm
2002/10/24
できん。
NEW してからでないと、クラスは使えないみたい。
2002/11/12
強制リブートやシャットダウンを行なう際、起動中のプロセスがあると、落とせないことがある。それを可能にするための手法についての考察を行なう。
2002/11/13
ヘルプには、
コレクション、オブジェクト、またはユーザー定義型を構成する要素。
と書いてあるが、実際は入らないジャン。オブジェクトしか入れれないよ〜
2003/01/29
方法1 アイコンプロパティを「BS」ボタンなどで、(なし)にする。
方法2 Me.Icon = Nothing Set文をつけないことがポイント
2003/04/09
以下の手順で実装したとき、不具合が発生した
つまり、エラーの内容が消えてしまったという話。
やっかいな事に、IED環境で動作検証すると、エラーナンバーなどは消えていないのです。
予想として、エラーナンバーが消えたのは、MsgBoxが内部でAPI関数をCALLし、その結果は正常復帰しているので、エラーナンバーが消えたのでしょうか...
このケースの対応方法としては、エラーナンバーなどの情報は、ハンドラーの頭で退避する等の考慮が必要という事で処理しました。
「IDEだと発生しない」に関しては、IED側がデバッグのアタッチをする時に、特別なシカケを持ち込んでいるのかもしれませんねぇ〜。
2003/07/04
ただしくパスを切ったハズのDLLが見つからないとき、そのDLLが内部で読んでいるDLLが見つけられない時にも、53が表示される。
紛らわしい〜
2003/07/04
更に、DEFファイルを使われていないDLLの場合は、名前が見つけられなくて、「ない」って言っているかもしれない。
やっぱりVBから呼ばれるDLLは、__stadcall が必須で defファイルで名前を修飾しておかないとあかんですね〜
2003/07/14
そこで、
ダミーのフォームを作成し、そこにアイコンを設計時に取りこんでおく。実行時、frmA.icon = frmB.icon
で、アイコンの取得及び複写ができる。これを関数化すれば良い。
つまり、frmBのアイコンさえ取込なおせば、あとは全てアイコンが切り替わる事になる。無論、実行環境には、アイコンファイルは不要である。
注意事項はfrmBからアイコンを取得した時に、frmBのインスタンスが生成されてしまうので、Unloadする事を忘れずに行なうこと。
ベストな方法ではないけど、運用面を考えれば検討の価値ありかも
2003.07.31
詳細エラーコードを取得したい時は、Err.LastDllError を使用すること。
2003/08/11
exeと同じフォルダに、exe名.manifestを配置すればよい。
これは、.NETアプリケーションだけ有効になるものでもなく、WindowsXP自体が、XMLファイルによりLook&Feelを指定できる機能を保有しているからである。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
processorArchitecture="x86"
version="1.0.0.0"
type="win32"
name="VB6.EXE"/>
<description></description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="x86"/>
</dependentAssembly>
</dependency>
</assembly>
これはVB6のIDEに対して設定したものである。すると、IED内で開発中のものまで、対応してくれる。
注意事項
VB6で作成したアプリケーションに、この技を適用する場合、以下の不具合が見受けられる。
フレーム内に配置した、コマンドボタンの枠が異様に太い、オプションボタンの背景色が真っ黒
フレーム内の不具合については、MSDNでも認めているようである。コマンドボタンなどをイメージリストコンテナに格納し、それをフレームに格納すれば表面上回避できる。
あとMicrosoft Common Controls 6.0 SP4 はLookが変更されない。
Microsoft Common Controls 5.0 SP2 は、変更が有効になるようだ。
manifestファイルは、リソースファイルとしてexe内に組み込みが可能であり、配布がスマートになる。が、VB用のリソースエディタ、VC++エディタでも、うまくいかなかったとネットにあったようだ
Look&Feelを特に意識していないアプリケーションは、中途半端にlookが変更される。
フォームのヘッダや、スクロールバーなどがその例である。
exeのプロパティから「視覚テーマを無効にする」をチェックすれば
無効になるようである。
2003/09/05
パスワード設定無しのスクリーンセーバー | パスワード設定有りのスクリーンセーバー | |
通常のメッセージボックス | メッセージボックスが表示されるが、スクリーンセーバーは解除されない。 | メッセージボックスが表示されるが、スクリーンセーバーは解除されない。 |
システムモーダルのメッセージボックス | スクリーンセーバーが解除されて、メッセージボックスが表示される。 | メッセージボックスが表示されるが、スクリーンセーバーは解除されない。 |
2003/09/10
Shell "command.com /c test.bat", vbHide
/c は実行環境後、復帰するスイッチ
vbHide をつけると、DOS窓が画面上に表示されなくなる。
2003/10/02
通常、上記の要件を実装する場合は、同一EXE内で、下記のように実装する
frmKodomo.Show vbModeless, frmOya
こうすれば、frmKodomo のオーナーがfrmOya となり、frmOyaを最小化した時にも、frmKodomoも最小化され、美しい動きとなる。
しかし、frmKodomo と frmOya を異なるexeとして実装したい場合は、以下の方法で実装できる。
親側
Dim lngMeHandle As Long
Dim strMeHandle As String
Dim strShellString As String
lngMeHandle = Me.hWnd
strMeHandle = CStr(lngMeHandle)
strShellString = "ko.exe " + strMeHandle
Shell strShellString, vbNormalFocus
子供側
Option Explicit
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_HWNDPARENT = (-8)
Private Sub Form_Load()
Dim strParameter As String
Dim lngHandleParent As Long
strParameter = Command$
If strParameter <> "" Then
lngHandleParent = CLng(strParameter)
Call SetWindowLong(Me.hwnd, GWL_HWNDPARENT, lngHandleParent)
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call SetWindowLong(Me.hwnd, GWL_HWNDPARENT, 0)
End Sub
解説
子供側で、SetWindowLongを使用し、Windowスタイルを変更する。変更内容は、親を変更する事である。親フォームのハンドルが必要となるが、この例では、文字列化する事により、起動引数として取得している。
なお、アンロードイベント時に、親ハンドルをクリアしているのは、親子関係を解消しておかないと、子供の終了時に落ちるという噂があったので、入れてある。
http://www.snark.co.jp/soft/faq/VB_A2.HTM#Q15
2003/10/27
単純に実験したところ、32757文字までだった。それ以上の文字を与えた場合は、無視された。
ところで、String型の説明を読むと
文字列型 (String) には、約 63KB までの長さの固定長文字列、約 2GB (20 億文字) までの可変長文字列を格納できます。
とあるので、固定文字列長の制限に影響されているかもしれませんねー
2003/11/07
Format関数は、四捨五入
代入は、丸め
3 = Format(2.5,"0")
2 = CLng(2.5)
[VB4] データ型と演算誤差についての注意 2004/01/28
Implements ClassName 継承ができるとヘルプには、書いてあったが、継承元クラスのメソッドを全てオーバーライズしなければならない。つまり、この機能は、インターフェイスの継承に有用である。
ちなみに、フォームオブジェクトでもImplementsを使用することにより、インターフェイスを用い簡易ポリフォーイズムを実装することができるみたいだー。
2004/01/30
TABSplitは、マウスダウンの直後に選択タブが切り替わる
表示要素を切り替える為にクリックイベントをトリガーにすると、TABSplit上でマウスアップに効かないと、クリックが発生しないのでタブだけ変わって、表示要素が切り替わらないという減少が発生することがある。
ならば、SSTABにすると良いのだが、たまたまあるプロジェクトでキャプションを太字に指定すると、アクティブなタブだけが、通常文字に切り替わってしまった
結論
TABSplitを採用
イベントは、マウスダウンでタイマーイベント経由で表示要素を切り替えた
2004/02/04
普通、メッセージボックスが出ている時は、他の処理はできないものである。よって、メッセージボックスが2つ出ることは無いと感じられる。それは、マルチスレッドでは無いから〜。
しかし、メッセージボックスで応答待ちになっている時に、タイマーイベントに起因するロジックは、走るようである。
Private Sub Command1_Click()
MsgBox "Command1_Click"
End Sub
Private Sub Timer1_Timer()
MsgBox "Timer1_Timer"
End Sub
ただしEXEにしてからでないと、再現できない。IDE配下だと再現できない。
2004/02/26
IDEを起動しているディスプレーの論理サイズより、大きいサイズのフォームはデザインできないようである。
フォームレイアウトでも、下記図よりも大きいサイズは作成できなかった
こまったこまった。
さらに、大きな解像度で保存したプロジェクトを、小さいサイズのPCで、フォームリソースを開かずしてコンパイルした場合も画面サイズに縮小されてしまうようだ!
でかいテレビ購入する理由になるねー
2004/03/02
APIビュアーを参照すると、void型の関数は、sub として宣言されているようでした。
2004/04/19
フォーム側
関数など
エラーメッセージなど
20240916