CFileDialogにて表示するダイアログのサイズを変更したいと考えております。
アプリを起動して、ファイルを開くボタンを押下した段階で任意のサイズにて表示したいのですが、上手く行きません。
CFileDialogを派生して、OnSizeやOnInitDialog などでMoveWindowなどを行ったのですが上手く行かず・・・
何か方法、ありませんでしょうか。
ご存知の方、よろしければご教授願います。
Spy++で見るとわかりますが
CFileDialog(その派生)は入出力を扱う機能がメインで
表示されているのは別のダイアログです
イメージ的には
**************
[呼び出したウィンドウ]
↓
[表示されるウィンドウ](*1)
↓
[CFileDialog]
**************
こうなっています。
ので、CFileDialogから、GetParent()で*1にアクセスして
MoveWindowすればサイズ変更できます。
ですが、やってみるとわかると思うのですが
表示されてる多数のコントロール(リストボックスなど)は何も変わないので
これらも全部手動で変更する必要があります。
ここまでくると、CFileDialogにこだわるより
そっくりさんのダイアログを自作するほうが早いです。
環境が提示されてないんで WinXP sp2 VC++6.0 sp5 MFC で試してみた。
SetWindowsHookEx API で WH_CALLWNDPROCRET を指定して、フックプロシージャ内で WM_SHOWWINDOW 時に CFileDialog の親ウィンドウに対して SetWindowPos API を呼ぶ。
コントロールの面倒を見なくてもいけた。
>rin様
ご回答ありがとうございます。
CFileDialogの挙動、勉強になりました。
新規ダイアログの作成も視野に入れ、もう少し考えたいと思います。
>NGA様
ご回答ありがとうございます。
環境の件、記載無く申し訳ないです。
偶然ですが同一の環境で作成しています。
もしよろしければもう少し詳しくご教授願えますでしょうか。
フックプロシージャ内でCFileDialogの親を取得するあたりで躓いております。
簡単にまとめるとこんな感じになる。
static HHOOK g_hHookProcRet;
static HWND g_hWnd;
static RECT g_rectInit; // DoModal() を呼ぶ前に初期表示位置を設定しておく。
LRESULT CALLBACK CallWndRetFileDlgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0)
{
return ::CallNextHookEx(g_hHookProcRet, nCode, wParam, lParam);
}
LPCWPRETSTRUCT pMsg = reinterpretcast<LPCWPRETSTRUCT>(lParam);
switch(pMsg->message)
{
case WM_SHOWWINDOW:
if(g_hWnd && pMsg->hwnd == ::GetParent(g_hWnd))
{
::SetWindowPos(pMsg->hwnd, NULL, g_rectInit.left, g_rectInit.top,
g_rectInit.right - g_rectInit.left, g_rectInit.bottom - g_rectInit.top, SWP_NOZORDER);
}
break;
}
return ::CallNextHookEx(g_hHookProcRet, nCode, wParam, lParam);
}
CMyFileDialog::CMyFileDialog(BOOL bOpen, LPCTSTR lpszDefExt, LPCTSTR
lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd)
: CFileDialog(bOpen, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
g_hHookProcRet = ::SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetFileDlgProc,
NULL, ::GetCurrentThreadId());
}
CMyFileDialog::~CMyFileDialog()
{
g_hWnd = NULL;
if(g_hHookProcRet)
{
::UnhookWindowsHookEx(g_hHookProcRet);
g_hHookProcRet = NULL;
}
}
// CFileDialog::OnInitDialog() をオーバーライドして CFileDialog のウィンドウハンドルを取得する。
BOOL CMyFileDialog::OnInitDialog()
{
CFileDialog::OnInitDialog();
g_hWnd = GetSafeHwnd();
return TRUE;
}
Tab は入力できないのね。orz
NGA様
ソースの掲示、ありがとうございます。
なるほど・・
派生クラスにしてやる必要があったんですね。
参考にさせていただきます。
実装できましたらまた書き込みに参ります。
ありがとうございました。
教えていただいた方法で意図どおりの機能を実装することが出来ました。
ありがとうございましたm(_ _)m
ツイート | ![]() |