C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: CDM_GETFILEPATHが仕事をしない!!


(過去ログ 85 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■50394 / inTopicNo.1)  CDM_GETFILEPATHが仕事をしない!!
  
□投稿者/ Z (1回)-(2010/06/05(Sat) 23:18:27)

分類:[C#] 

お世話になっています。
OpenFileDialogのカスタマイズというよくあることをやっていたのですが、
変な事象が発生したので、ご教授して頂けないでしょうか。

変な事象というのはWindowsVistaで「CDM_GETFILEPATH」が仕事をしないという事象です。
(XPやWin7の環境がないため、Vista以外では確認しておりません)

ソースは以下の通りです。お目汚しなソースですが、ご容赦ください。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        internal static extern IntPtr CreateWindowEx(
           uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y,
           int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);

        const uint WS_VISIBLE = 0x10000000;
        static readonly IntPtr HWND_MESSAGE = new IntPtr(-3);
        static readonly IntPtr NULL = IntPtr.Zero;

        public static IntPtr target = IntPtr.Zero;

        public Form1()
        {
            InitializeComponent();

            IntPtr dummy = CreateWindowEx(0, "Message", null, WS_VISIBLE, 0, 0, 0, 0,
                HWND_MESSAGE, NULL, NULL, NULL);

            new HandlerHelper().AssignHandle(dummy);

            OpenFileDialog dlg = new OpenFileDialog();

            dlg.ShowHelp = true;

            dlg.ShowDialog(this);

            dlg.Dispose();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (target != IntPtr.Zero)
            {
                StringBuilder filePath = new StringBuilder(256);
                uint cd = 0x0465;//CDM_GETFILEPATH;
                SendMessage(target, cd, (IntPtr)256, filePath);
                Debug.WriteLine(filePath.ToString());
            }
        }

        public class HandlerHelper : NativeWindow
        {
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 0x0006) //WM_ACTIVATE
                {
                    if (Form1.target == IntPtr.Zero)
                    {
                        Form1.target = m.LParam;
                    }
                }

                base.WndProc(ref m);
            }
        }
    }
}


この状態で実行すると「CDM_GETFILEPATH」はちゃんと仕事を行い、
選択しているファイルを取得してきます。

しかし、

//dlg.ShowHelp = true;

とし、ヘルプボタンを表示しないようにします。
そうすると、「VistaっぽいOpenFileDialog」になるのですが…

これで実行すると、「CDM_GETFILEPATH」は仕事をしてくれません。

いろいろググってみたのですが…原因が分かりませんでした。

どなたかご教授して頂けないでしょうか。



引用返信 編集キー/
■50396 / inTopicNo.2)  Re[1]: CDM_GETFILEPATHが仕事をしない!!
□投稿者/ Z (2回)-(2010/06/06(Sun) 00:05:23)
恥ずかしながら自己レスです。

AutoUpgradeEnabledがtrue(デフォルト)

だとIFileDialogの方に委託されるようですね…
Vistaのスタイルのファイルダイアログだと、
XP以前のやつと根本的に異なってしまうのですね…

だから「CDM_GETFILEPATH」が仕事しないのか。

IFileDialogを調べれば解るのかもしれませんが、
ググってもあまりサンプルがヒットしませんし…



引用返信 編集キー/
■50398 / inTopicNo.3)  Re[2]: CDM_GETFILEPATHが仕事をしない!!
□投稿者/ Hongliang (644回)-(2010/06/06(Sun) 05:27:53)
IFileDialog については、Windows API Code Pack for Microsoft .NET Framework などで実装されています。
http://code.msdn.microsoft.com/WindowsAPICodePack
……が、SelectionChanged イベントはあるのにこのイベント中は FileName を取得できないようですね。
IFileDialog::GetCurrentSelection を使うプロパティを用意するなりすればどうとでもなりますが。

まあこれを System.Windows.Forms.OpenFileDialog に組み込むとか流用するとかは無理筋ですけど。OpenFileDialog が内部で扱っている IFileDialog は基本的に手出しできないところですし、ウィンドウハンドルからどうこうできる物でもありませんし。
かといって CodePack の CommonOpenFileDialog に完全に移行するのは、XP 以前にも対応が必要な場合は不可能ですね。
GetOpenFileName に渡すフック関数では WM_NOTIFY/CDN_SELCHANGE で選択項目変更も通知されるみたいですから、いっそ OpenFileDialog を自前で実装しちゃうのもありかも(System.Windows.Forms.OpenFileDialog と同様に、表示できる場合は IFileDialog(というか CodePack の CommonOpenFileDialog)を表示するようにする)。
引用返信 編集キー/
■50409 / inTopicNo.4)  Re[3]: CDM_GETFILEPATHが仕事をしない!!
□投稿者/ Z (3回)-(2010/06/06(Sun) 20:17:58)
回答ありがとうございます。
VC#でCOMやるのはシンドイので、
時間があればVC++でIFileDialogを調査してみたいと思います。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -