- ベストアンサー
VB6 ClassにてEnum(列挙型)のうまい使い方
へっぽこPGです。 今まで私の質問にご回答を頂いた方々、改めてお礼申し上げます。 最近VB6でActiveXDLLにて、DLLを作り始めました。 Classについて勉強を始めたばかりで、 実現できそうな機能と実現できない力量のギャップに苦労しています。 さて、いろいろと便利なDLLを作ってやるぞ!と意気込み、 ExeからDLLを参照してプロパティに値を設定する時に、 インテリセンスが出るようにしたく、ClassにEnum(列挙型)を使うやり方を見つけましたが・・・・。 その先困ってます。 VB6でデバッグをしているわけですが、 Class(Dll)とExeは別プロジェクトで生成しており、 Dllはバイナリ変換、デバッグはExeを実行するように設定済です。 これでActiveXDLLプロジェクトで「開始」をすると、Exeを実行してくれます。 Exeのプロジェクトから、 「開始」・ステップ実行して確認しましたが、 正常に動作しているようです。(記述した文がそれぞれ機能しているという意味で) ActiveXDLLプロジェクトから、 「開始」後、「停止」をして、Dllを上書きしようとすると、 「書込みできません。"~DllのPath~"」とMsgboxのBouttonのでいうvbMsgBoxStyle=vbCriticalの形式で、 Msgboxが表示されてしまいます。 どうやらExeがDLLを離していないのでしょうか? もちろん列挙型を設定していないDLLの場合ですと、上書きは可能です。 (他にも上書きできないパターンを見つけましたが、話が脱線するので割愛します。もしご存知でしたら、併せて教えて頂くと幸いです。) 困っている点としては、 1 デバッグする上で、Dll(書出)⇔Exe(開始)を繰り返したく、都度プロジェクトを閉じて、開いてDLL書出しするのは、非効率。 (DLLを書き出して、インターフェースを変えてしまえば、Exeはリコンパイルが必要なので、あんまり意味ないかも・・・とも) 2 読み取り専用プロパティを作って、Initializeで初期値を設定してしまう方法を考えたが、非常にかっこ悪いし、運用が大変。 3 1を我慢したとしても、作成したDLLはCOM+に登録して、WebサーバでASPから使用するつもりなので、DLLを離してくれないと、無駄なプロセス動き続けてしまう(?)→未テスト です。 いろいろとツッコミどころがあるかもしれませんが、 忌憚なくご意見下さい。 ---Class-(test_Class)---- '列挙宣言 Public Enum Chiiki Hokkaidou = 0 Aomori = 1 Akita = 2 End Enum 'プロパティ値を格納しておく変数 dim aaa as integer 'プロパティでEnum宣言した型を引数に指定します、 Public Property Get Shusshin() As Chiiki Shusshin = aaa End Property Public Property Let WindowState(ByVal NewValue As Chiki) aaa = NewValue End Property ---Class-End-------------------- ---Exe----------------- 'Classは参照設定にて '参照設定にしている理由としては、インテリセンスでロパティ・メソッド等を利用したいから。開発側の怠慢? Sub a 'Class宣言 Dim a_class as test_Class Set a_class = New test_Class 'プロパティ設定 ↓ = と打つと、Classの列挙で設定した値がプルダウン a_class.WindowState = Aomori 'プロパティ値表示(処理自体に意味無し) '「1」 と表示される Msgbox a_class.WindowState 'Class開放 Set a_class = nothing End sub ---Exe-End----
- chun_rock
- お礼率100% (5/5)
- Visual Basic
- 回答数3
- ありがとう数5
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
VB6が DLLを離していないためですよ VB6のインスタンスが2つある状態なのですよね VB6-ActiveXとVB6-TextExeが起動している状態で VB6-TestEXEが参照設定のため DLLをつかみっぱなしになっています DLLが開発途上なら プロジェクトグループで開発したほうが良いと思います DLLプロジェクトとテスト用EXEプロジェクトを1つのグループにして開発orデバッグします どちらでも良いですからプロジェクトを開いて ファイル > プロジェクトの追加 で他方のプロジェクトを追加します テスト用EXEプロジェクトに参照設定をして開発します DLL側の修正はそのままコードウィンドウを開いて編集します DLLファイルの作成し直しは プロジェクトウィンドウで DLLプロジェクトをアクティブにして ファイルメニューからDLL作成をします テストEXEのデバッグには プロジェクトウィンドウでEXEプロジェクトをアクティブにしてからデバッグ実行などをします
その他の回答 (2)
- Asarima
- ベストアンサー率50% (1/2)
列挙型だけを記述したDLLを別に作成するのがおすすめです。 ExeからもDLLからも、そのDLLを参照設定しておけば、 どちらからも同じ列挙型が使えますし、インテリセンスも効きます。 以前、そのような構成の開発を経験したことがあるので。
お礼
ご回答ありがとうございます。 なるほど、スマートな方法ですね。 DLLとExeの関係(クラス構造?)がなるべく煩雑にならないように・・・ と考えましたが、甘い考えかもしれませんね(笑) どこまで部品化するか・・・、考えればキリがなさそうです。 今の業務は、システムが幾つも散在していて、 無駄だらけです。 コーディング技術というよりも、 詳細・概要・・・その上の設計を学ぶべきところでしょうか。 余談ですが、 回答には回答日時がありますが、 お礼にはお礼日時がありませんね。 運用でカバーしましょう(笑) 2007/10/05 9:45:16 尚、ANO2のお礼は、上記数分前です。
- redfox63
- ベストアンサー率71% (1325/1856)
テストEXEプロジェクトをアクティブにすると プロジェクトウィンドウのテストEXEプロジェクトが太字になるかと思いますがなりませんか? そのプロジェクトを選択して右クリック > スタートアップとして設定で出来ると思います ここが太字になっていないと DLL側のデバッグ設定が使われると思います
お礼
何度もご回答本当にありがとうございます。 Exeプロジェクトが「開始」していることを確認しました。 が、やはりDLLは上書きできませんでした。 このパターン(列挙型使用)だと、 Exeが参照設定でDLLを離さない理由がわかりません。 ・・・というか、たった今解決してしまいました。 (?暫定対応?代替案?) DLLのコンパイルを、 バイナリ互換でなく、プロジェクト互換でやると、 問題なく上書きできました。 (以下、こちらのサイトで「プロジェクト互換」で検索した結果の一部) VB DLLプロジェクトについて http://oshiete.nikkeibp.co.jp/qa1648268.html インターフェイスIDを変えずにVBのDLLをリコンパイルするには? http://oshiete.nikkeibp.co.jp/qa13566.html プロジェクト変換 インターフェースIDが変更されるから、 参照設定しているVBのAPは、リコンパイルが必要。 →運用を考えると、好ましくない。 (APが増えれば、作業は甚大だし、管理が煩雑になる恐れ有・・・。 しかしながら、DLLとAPの関係を把握していないわけはないので、 作業面だけが問題か?) バイナリ互換 インターフェースIDが変更されないから、 参照設定しているVBのAPは、リコンパイルが不要。 但し、(下記「VB DLLプロジェクトについて」抜粋) 1.実装済みメソッドの戻り値の型を変更できない。 2.引数の型及び個数を変更できない。 3.メソッドを追加した場合、COMクライアントの再コンパイルが必要。 (CreateObjectは別) であるので、結局はリコンパイルが付き纏う。 (COMクライアントが、 COMを使っているAPのりコンパイルを指すのか、 コンポーネントサービス>COM+アプリケーション>コンポーネント の 再設定を指すのか、不明。) 上記と、今回の現象と、開発のし易さを考慮すると、 DLL・・・開発中はプロジェクト互換で、リリース時にはバイナリ互換で。 DLL使用するAP等・・・開発中は参照設定で、リリース時にはCreateObjectで。 という結論に落ち着くでしょうか。 「理由は何だかわからないけど、こうすればうまくいく」 という危ない状態でしょうが、方向が間違ってなければ良しとする。 ・・・悪い傾向です。
関連するQ&A
- enum列挙子に使える文字列と使えない文字列
enum Ok{A,A,月1,月1,_,?} enum Ng{1月,1月,→,!,☆} public class Main{public static void main(String[] args){ System.out.println("あああああ"); }}//終わり このJavaプログラムはエラーになります。何故ですか? 要するに、enumに使える列挙子の法則性に興味があります。「?」は通って「!」はエラーって、コンパイルを試みた後に結果を知ると、色々とムカつきます。 「!」は通って「?」はエラーだと嘘が書物に書いてあると、騙されます。 enumで使える列挙子(要素)のタイプが載ってるサイト、enumの列挙子に使うとエラーになってしまう例が載ってるサイトなどを紹介してくれるとありがたいです。 どんな文字列でもenumに使えて、何でもOKなら親切だと思うのに・・・
- ベストアンサー
- Java
- VB.NET クラス内でプログラムを終了するには?
VBAでは、エラーでプログラムを終了する時には Endステートメントを記述していましたが、 このVBAをVB.NET(クラスライブラリ、DLL)に 書き換えていますが VB.NETでClass1クラスの中にtest()メソッドを作って この中にEndステートメントを記述すると 「クラスライブラリプロジェクトで Endステートメントを使用することができません。」 というメッセージが表示されますが エラーでプログラムを終了するには どのように記述すればいいのでしょうか。 Public Class Class1 Public Sub test(ByVal a As String) If a = "" Then MsgBox("致命的なエラーです") End <===エラー発生 End If End Sub End Class よろしくお願いします。(WindowsXP,VS2010)
- ベストアンサー
- Visual Basic
- 整数の引数に列挙を使ったとき
下記のサンプルコードでVB2003のときは警告が出なかったのですが、VB2008では警告が出ます。(注!インデントに全角スペース使用) Private aryNames(5) As String Private Enum enmItem As Integer eName1 = 0 eName2 eName3 End Enum Private Sub Form1_Load(… Dim i As Integer Dim en As enmItem '列挙を使って代入する Item(en.eName2) = "DATA2" Item(en.eName3) = "DATA3" Item(en.eName1) = "DATA1" 'リストボックスで確認 For i = 0 To 2 ListBox1.Items.Add(aryNames(i)) Next End Sub Private Property Item(ByVal idx As Integer) As String Get Return aryNames(idx) End Get Set(ByVal Value As String) aryNames(idx) = Value End Set End Property 警告 使用されないローカル変数'en'です。 インスタンスを経由する共有メンバ、定数メンバ、列挙型メンバ、または入れ子にされた型へのアクセスです。正規の式は評価されません。 いちおう警告だけで期待通りの動きはするのですが、そんなに不正なコーディングでもないのに警告がでるのはうっとうしいです。 かといて警告オプション・・・ 未使用のローカル変数 なし 共有メンバにアクセスするインスタンス変数 なし ・・・とするのも何だかなあ~ て感じです。 これは、安全なコーディングのため仕様が変わったせいなのでしょうか。 警告オプションをそのままに、上記の警告が出ないようにできないものでしょうか。 以上、よろしくお願いします。
- ベストアンサー
- Visual Basic
- ActiveXDLLのコンパイル時にLeft関数でエラー
普段VisualBasic6.0を使ってプログラミングをしており、通常は標準のEXEを作るプロジェクトを使っています。 今回、ActiveXDLLにてDLLを作ろうとプログラミングをしてコンパイルをかけたところ、Stringの操作を行う、Left、Right、Midなどの基本的な関数のところで、 「プロジェクトまたはライブラリが見つかりません」 というエラーが出ます。これは何か設定が必要なのでしょうか。 それとも、ActiveXDLLを作るときにはLeftなどの関数を使うことはできないのでしょうか? どうぞよろしくお願いします。
- ベストアンサー
- Visual Basic
- VB6で作成した自作DLLをVB.NETで呼び出し例外発生時に参照渡しの引数に値を設定する方法
VB6で作成した自作のDLLをVB.NET2005で作成したEXEから呼び出した際に、DLLメソッドの正常・異常終了に関わらず第2引数の戻り値に第1引数の値を設定したいと考えていますが旨くいきません。 何かよい方法はないでしょうか? 以下、簡単なサンプルです。 =========================== VB6 DLL =========================== Public Sub getDataForTest(ByVal strIn As String, ByRef strOut As String) Dim intData As Integer 'strInの値をstrOutに代入 strOut = strIn 'strInの値を1で割り算 intData = CInt(strIn) / 1 End Sub =============================================================== =================== DLL呼び出し正常パターン =================== Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim objCom As New Project1.Class1 Dim strRet As String = "" Try Call objCom.getDataForTest("1", strRet) Catch ex As Exception MsgBox(ex.Message) Finally MsgBox(strRet) ←←← 1が表示される End Try End Sub =============================================================== =================== DLL呼び出し異常パターン =================== Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim objCom As New Project1.Class1 Dim strRet As String = "" Try Call objCom.getDataForTest("A", strRet) Catch ex As Exception MsgBox(ex.Message) Finally MsgBox(strRet) ←←← この時にAを表示したいがstrRetが空 End Try End Sub ===============================================================
- 締切済み
- Visual Basic
- VB.NET 自作プロパティが変更されたらイベント
お世話になります。 ご回答宜しくお願いします。 現在VBでDLLプログラムを開発しております。 以下簡単な仕様です。 DLLで自作のプロパティ( SelectedFlg )と、 SelectedFlgが変更された時に発生するイベントを追加しました。 親システムからVBのDLLを呼び出し、親システムがSelectedFlgの値を変更すると DLL内でイベントを感知し、処理をするというような感じです。 例えば、親システムへDLLをパネルとして2つ( A , B )貼り付け Aをクリックすると、AのSelectedFlgをTrueに、BのSelectedFlgをFalseにして Trueの方はBackColorを赤、Falseの方はBackColorを白 のような形にしたいと考えてます。 しかし、実行してみると BackColorが反映されるのは、初期値を設定した時の1度のみでした。 その後クリックしても、BackColorが変化することはありません。 どこか間違いや思い違いがあるんでしょうか。 以下コードになります。 ・・・OriginalControlクラス・・・ Public Class OriginalControl Public Event SelectedValueChanged(ByVal sender As Object, ByVal e As EventArgs) Protected Sub OnSelectedValueChanged(ByVal e As EventArgs) RaiseEvent SelectedValueChanged(Me, e) End Sub Public Property SelectedFlg() As Boolean Get Return m_SelectedFlg End Get Set(ByVal value As Boolean) m_SelectedFlg = value Me.OnSelectedValueChanged(New EventArgs) End Set End Property Private m_SelectedFlg As Boolean End Class ・・・Panel・・・ OriginalControlクラスを継承したControl ( 省略 ) Private Sub Panel_SelectedValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.SelectedValueChanged If Me.SelectedFlg = True Then setBackColor( Color.Red ) Else setBackColor( Color.White ) End If End Sub
- 締切済み
- Visual Basic
- VB2010のプロパティの読み書き処理
VB2010で作成したEXEプログラムがあります。 このプログラムを別のVB2010で呼び出しています。 Shell("K:\Test.exe", vbNormalFocus) フォームは最大化して、Test.exeを任意の位置に 表示させたいのですが、Test.exeのプロパティを 書き込む方法がわかりません。 Test.exeのプロパティはMy Projectの設定で My_x Integer ユーザー 0 My_y Integer ユーザー 0 としています。 Test.exeでは位置の設定は Dim i As Integer = My.Settings.My_X Dim j As Integer = My.Settings.My_Y With Me .Top = j .Left = i End With どなたか教えてもらえませんか。
- ベストアンサー
- Visual Basic
- VB .NetのDLL参照について
名前付パイプの処理をしているのですが、DLLが参照できません。 Public Class ClsJi01 Public Declare Function MakePipe Lib "\DLL\Point.DLL" (ByVal pipe_name As String, ByVal buf_size As Integer, ByVal max_instances As Short, ByVal hpipe As Integer, ByVal err_code As Integer) As Integer Public Sub M_Pipe() Dim r As Integer Dim rpipe As Integer Dim err_code As Integer r = MakePipe("\\.\pipe\RS04", 255, 16, rpipe, err_code) End Sub End Class Point.DLLは以前VB6.0の時に使用していたDLLで自作です。 これで実行すると「オブジェクト参照がオブジェクト インスタンスに設定されていません。」と出ます。 どうしたら良いのでしょうか?
- ベストアンサー
- Visual Basic
- *.exeと異なるフォルダのDLLをみにいく様に設定するには?
環境 Windows VISTA SP1 Visual Studio 2008 今現在、ビルドすると、releaseというフォルダにA.exeが 作成されます。そして、同一のプロジェクトにDLL生成プロジェクトを 追加してあり、同じreleaseというフォルダに B.dllが生成される様に設定してあります。 この状態で、A.exeをたたけば、B.dllを認識して立ち上がってくれます。 しかし、最近、dllを作るプロジェクトが大量になってしまい、 releaseフォルダが結構たくさんになってしまっています そこでA.exeをたたいたら release/dll というフォルダをみにいって起動してくれる様に改良 したいのですが どうしたらよいでしょうか? *exeを追記しているslnのプロパティを一通りみたのですが よくわかりません。
- 締切済み
- C・C++・C#
- ArrayListの初期値の設定の仕方(VB.NET)
VB.NET2005についての質問です。 ArrayList型の変数の初期値に、プロパティの戻り値を設定することは可能でしょうか。 (つまり、下記の(a)(b)の二行を一行にまとめたい、と考えています) どうぞよろしくお願い致します。 Public Class form1 Dim hoge As New ArrayList 'a)初期値としてClass1.P_hogeを設定したい hoge = Class1.P_hoge 'b)消したい End Class Public Class Class1 Private Shared _hoge As New ArrayList 'すでに値が格納されているものとする Public Shared Property P_hoge() As ArrayList Get Return _hoge End Get End Property End Class
- ベストアンサー
- Visual Basic
お礼
早々のご回答ありがとうございます。 ご助言の通りグループプロジェクトを作成しましたが、 DllプロジェクトにてExeを起動させる設定をしないと、 何も実行されません。 (Exeプロジェクトウィンドウをアクティブにして「開始」しても、 どうやらDLLプロジェクトの設定しか有効でないようで) 設定をしてしまうと、 DllプロジェクトでExe起動するパターンと同現象が発生します。 私自身、 グループプロジェクトは、 Dllプロジェクト単体でEXE起動設定をした場合と、 同じ状態にしかもっていけなかったので、 グループプロジェクトを使っていなかったという経緯があります。 >もちろん列挙型を設定していないDLLの場合ですと、上書きは可能です。 の通り、列挙型をPublic設定しているからが要因かと思っていましたが・・・。 申し訳御座いませんが、 グループプロジェクトについて、もう少しご説明頂けないでしょうか?