ファイルを開くダイアログについて

タグの編集
投稿者 四月一日(ワタヌキ)  (社会人) 投稿日時 2009/12/30 01:41:00

VB6にてファイルを開くコモンダイアロゴを表示する
プログラムを作成し、EXEを作ったところ
ある端末(PC)にて実行時エラーが出てしまいます。

場合によって次のどちらかが出ます。
 1.実行時エラー393 leftプロパティの値の取得は出来ません。
 2.実行時エラー383 Heightプロパティは値の取得のみ可能です。

エラーの原因が分かりません。

判るかたが見えましたら、教えてください。
よろしくお願いします。
投稿者 るしぇ  (社会人) 投稿日時 2010/1/7 20:37:06
そもそも、VB6 の
コモン ダイアログ (CommonDialog) コントロールには、
left プロパティも Height プロパティもありません。

つまり、エラー内容とファイルを開くダイアログが
直接関係無いことがすぐに分かるのですが、
> エラーの原因が分かりません。
としか言えない時点で、プログラムを勉強してない人だ
という事が分かります。

勉強しない人に教えても意味ないですよね?
だからコメント付かないんじゃないかと思います。

そういう人は、お金を払って正式なメーカーサポートを
受けるべきだと思います。VB6 は開発面でのサポートは
終わっているので、VB.NET に乗り換えてメーカーサポートを
受ける事をお勧めします。
とはいえ、メーカーサポートが親身になって解決してくれる
わけでもないですけどね。情報が足りなければ
「再現しませんでした」の一言で切られます。
自分で原因追求する意思が無いという時点で、どれだけ
甘いのか知っておくべきでしょう。
投稿者 るしぇ  (社会人) 投稿日時 2010/1/7 20:52:55
> コモン ダイアログ (CommonDialog) コントロールには、
> left プロパティも Height プロパティもありません。
あ、ゴメン。Left と Top はあったわ。
コード上の入力候補及びオブジェクトブラウザに出てこなかったから、
無いと判断したけど、デザイン画面で設定できます。

あと、ヘルプにも解説がありますね。
>Left、Top プロパティ
> コモン ダイアログ (CommonDialog) コントロールおよびタイマー (Timer) コントロールの場合は、
> これらのプロパティは実行時には設定できません。
投稿者 るしぇ  (社会人) 投稿日時 2010/1/7 21:12:39
おわびついでに、
CommonDialog コントロール自身の left プロパティや Height プロパティ
を設定しようとしたという事は、コモンダイアログの表示位置を変更
しようとしたという事でしょう。

正規の方法はありません。正攻法で攻めるならサブクラス化は
必須でしょう。が、ダミーでフォームを別に用意して工夫する案が
あります。
検索キーワード「コモンダイアログ vb6 位置」
投稿者 (削除されました)  () 投稿日時 2010/1/7 22:42:27
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/1/7 22:43:27
> VB6にてファイルを開くコモンダイアロゴを表示する
> プログラムを作成し、EXEを作ったところ
ダイアロゴ ⇒ ダイアログ の誤記は別として、上記は
VB6 の CommonDialog コントロールの事を指しているのですよね?
(EXE ということは、VBA6 の間違いでも無さそうですし)

> 1.実行時エラー393 leftプロパティの値の取得は出来ません。
質問内容からは、その「leftプロパティ」がどのオブジェクトの left プロパティの事か
分かりませんので、どのような処理を行っているのか、該当箇所のコードを見せて頂けないでしょうか。

また、そのメッセージは一字一句違わず、正確なメッセージ内容でしょうか?
こちらでもいろいろと試してみたのですが、『leftプロパティの値の取得は出来ません。』という
メッセージを得る事はできませんでした。

# MSComDlg.CommonDialog には Left プロパティが無いので、
# 別のオブジェクトの left/Height を操作しようとしているのだとは思いますが…。

'実行時エラー382: 実行時には値を設定できません。 
'CallByName CommonDialog1, "Left", VbLet, 0 

'実行時エラー382: 'Left' プロパティは、実行時には設定できません。 
'Me.Controls("CommonDialog1").Left = 0 

'実行時エラー393: 'Left' プロパティは実行時に値の取得はできません。 
'MsgBox Me.Controls("CommonDialog1").Left 

'実行時エラー393: 実行時には値を取得できません。 
'MsgBox CallByName(CommonDialog1, "Left", VbGet) 

'実行時エラー438: オブジェクトは、このプロパティまたはメソッドをサポートしていません。 
'MsgBox CommonDialog1.object.Left 
'CommonDialog1.object.Left = 0 

'コンパイルエラー: メソッドまたはデータ メンバが見つかりません。 
'CommonDialog1.Left = 0 



> 場合によって次のどちらかが出ます。
もし、「ファイルを開く」ダイアログの位置調整を行おうとしているのであれば、
『画面中央に表示』程度の制御でよければ、MSComDlg の代わりに DialogObjects を
使う事ができます。


具体的には、"Microsoft Dialog Automation Objects" (DLGOBJS.DLL)を
参照設定して、下記のように記述すれば OK です。

Private Sub Command1_Click()
    Dim dlg As DialogObjects.ChooseFile
    Set dlg = New DialogObjects.ChooseFile

    dlg.Center = False

    If dlg.Show() Then
        MsgBox dlg.Directory & "\" & dlg.FileName, vbInformation
    Else
        MsgBox "キャンセルされました。"
    End If
End Sub


ダイアログの表示位置を、Center プロパティ(初期値は False)で
 True : 主画面の中央に表示
 False: 現在画面の左上に表示
のように切り替える事ができます。


DLGOBJS.DLL は通常、VB6 をインストールしたフォルダの
  VB98\Wizards\PDWizard\dlgobjs.dll
にあります(このファイルは標準再頒布可能です)。

また、"Microsoft Dialog Automation Objects" を参照設定できない場合には、
C:\Program Files\Microsoft Visual Studio\COMMON\Tools\VB\UNSUPPRT\DLGOBJ(もしくは、VB6 CD-ROM 内の Tools\VB\UNSUPPRT\DLGOBJ\)
にある DLGOBJS.REG をダブルクリックして、レジストリに登録すれば OK です。
投稿者 四月一日(ワタヌキ)  (社会人) 投稿日時 2010/1/13 07:49:31
みなさんありがとうございます。

ソースを掲載しますので、またよろしくお願いします。

=======================================
'特殊フォルダ取得
Public Declare Function SHGetSpecialFolderPath Lib "shell32.dll" Alias "SHGetSpecialFolderPathA" _
 (ByVal hwndOwner As Long, ByVal lpszPath As String, ByVal nFoder As Long, ByVal fCreate As Long) As Long
Public Const CSIDL_DESKTOP = &H0
Public Const CSIDL_DESKTOPDIRECTORY = &H10


Private Sub cmdRegist_Click()

    Dim sTemp As String
    Dim sRet  As String      
    
    On Error GoTo CANCEL_PROC
    cmnDlg.CancelError = True
    cmnDlg.Filter = "全てのファイル(*.*)|*.*"
   
   If デフォルトパスが設定されているか? Then
        sTemp = String(256, Chr(0))
        Call SHGetSpecialFolderPath(Me.hwnd, sTemp, CSIDL_DESKTOP, 0)
    Else
        sTemp = デフォルトパス
    End If
    
  cmnDlg.InitDir = Trim$(sTemp)
    'ファイル選択ダイアログ表示
    cmnDlg.ShowOpen  <-----------ここでエラーと思います???

    msFileName = cmnDlg.FileName
    
    'キャンセルボタンを押したとき
    If Trim(msFileName) = "" Then
        Exit Sub
    End If
    
    'ファイルが存在しないとき処理を終了する
    If Dir(msFileName) = "" Then
        sRet = MsgBox("該当ファイルが存在しません。", vbCritical)  
        Exit Sub
    End If

  --- 省略 ----
    
    Exit Sub

CANCEL_PROC:
    
End Sub
===============================================
以上です。

ファイル選択ダイアログが表示する前に
エラーになってしまいます。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/1/13 18:38:06
> If デフォルトパスが設定されているか? Then
>     sTemp = String(256, Chr(0))
>     Call SHGetSpecialFolderPath(Me.hwnd, sTemp, CSIDL_DESKTOP, 0)
> Else
>     sTemp = デフォルトパス
> End If

エラーが発生する場合、この部分では True 処理(If ブロック)と False 処理(Else ブロック)の
いずれが処理されていますか?


> cmnDlg.InitDir = Trim$(sTemp)
この部分の処理を見直しください。

sTemp の中身にもよりますが、先の SHGetSpecialFolderPath を通過していた場合、
文字列 sTemp の後半は Chr(0) で埋められているはずです。

しかし Trim 関数では Chr(0) を除去できません。Trim 関数で除去できる文字は、
全角空白(" ")と半角空白(" ")だけであることに注意してください。提示されたコードでは不完全です。

# CommonDialog.InitDir では、Chr(0) 以降の文字列が無視されるため、
# 結果として、この問題に気付きにくいかも知れませんが。


> cmnDlg.ShowOpen  <-----------ここでエラーと思います???
ちょっと待ってください。
本当に、そこで発生するエラーが最初の質問にあった
> 1.実行時エラー393 leftプロパティの値の取得は出来ません。
> 2.実行時エラー383 Heightプロパティは値の取得のみ可能です。
という事なのでしょうか?
(提示されたコードには、どこにも left / Height の表示がありません)

本当は、別の箇所でエラーが発生していたりはしませんか?
あるいは、その場所で発生するエラーは、別の内容だったりはしませんか?


> 'ファイルが存在しないとき処理を終了する
> If Dir(msFileName) = "" Then
ShowOpen する前に、cmnDlg の Flags プロパティの値を、どのように設定していますか?

もし、既存のファイルのみを選択させたいのであれば、Dir で判定せずとも、
  cmnDlg.Flags = cmnDlg.Flags Or cdlOFNFileMustExist
というコードを事前に入れておくだけで済みますよ。


> ファイル選択ダイアログが表示する前に
> エラーになってしまいます。 
あれ? On Error GoTo CANCEL_PROC を組み込んでありますから、この Private Sub cmdRegist_Click() 内で
エラーメッセージが表示される事は無いと思いますよ。

それともこのコードは抜粋で、実際の cmdRegist_Click はもっと複雑なコードなのでしょうか?
(CANCEL_PROC ラベル以下に、エラーの内容を記述するコードが含まれているなど)
投稿者 四月一日(ワタヌキ)  (社会人) 投稿日時 2010/1/14 07:20:14
本日、無事解決しました。

コメントしていただいた方、
本当にありがとうございました。

魔界の仮面弁士さん
指摘のあったとおり、
別のところでエラーが発生しているのがわかりました。
細かく指摘していただきありがとうございます。