dポイントプレゼントキャンペーン実施中!

現在Win32 APIのGetOpenFileName/SetOpenFileNameを利用したファイルダイアログの作成をしているのですが、OPENFILENAME.FlagsにOFN_ENABLESIZING属性を、lpfnHookにイベントを取得する関数を設定した状態で、手動によるダイアログサイズの変更を行っても、WM_INITDIALOGやWM_NOTYFYイベントは受け取ることはできても、WM_SIZEイベントを受け取ることができません。

コモンダイアログのウィンドウサイズが変更されたことを知る方法はないでしょうか。

A 回答 (5件)

#1です。



「 親ダイアログのWM_SIZEイベントを取得できるようにするAPIなどがあればお教え下さい。」
ハイ、APIは #3のコードの中にある GetParent と SetWindowLong です。でもそのような質問を
される段階ならば、まずは「サブクラス化」について調べてみることをお勧めします。

#3の投稿によると 「//2回親を取らないと親ダイアログに辿りつけない」とのこですが、
確認のため試してみました。でも、フックダイアログの一つ上の階層が GetOpenFileName で
呼び出されるダイアログでした(SPYで確認)。

フックダイアログ一つ上の階層のダイアログにて WM_SIZE もマウスドラッグに応じてイベントを
取れました。コードを付けときますが、全角スペースでインシデントしてますので、変換してください。


//////////////////////////////////////////////////////////////////////////////
// resource.h

#define IDD_DIALOG1 101

//////////////////////////////////////////////////////////////////////////////
// resource.rc

#include "resource.h"
#include "afxres.h"

IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 187, 90
STYLE WS_CHILD
FONT 9, "MS Pゴシック"
BEGIN
END

//////////////////////////////////////////////////////////////////////////////
// sample.cpp

#include <windows.h>
#include "resource.h"

UINT CALLBACK OfnTopDlgProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
UINT CALLBACK OfnHookDlgProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);

DLGPROC OfnOrgTopDlgProc;

//--------------------------------------------------------------------------

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR pszCmdLine, int nCmdShow)
{
  char fileName[MAX_PATH] = {0};
  OPENFILENAME ofn = {0};

  ofn.lStructSize = sizeof(OPENFILENAME);
  ofn.hInstance = hinst;
  ofn.lpstrFile = fileName;
  ofn.nMaxFile = sizeof(fileName);
  ofn.Flags |= OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING;
  ofn.lpfnHook = OfnHookDlgProc;
  ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);

  ::GetOpenFileName(&ofn);

  return 0;
}

//--------------------------------------------------------------------------

UINT CALLBACK OfnTopDlgProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
  char buff[128];

  switch(wm){
    case WM_SIZE:
      ::wsprintf(buff, "WM_SIZE (%d, %d)\n", LOWORD(lp), HIWORD(lp));
      ::OutputDebugString(buff);
      break;
  }

  return ::CallWindowProc((WNDPROC)OfnOrgTopDlgProc, hwnd, wm, wp, lp);
}

//--------------------------------------------------------------------------

UINT CALLBACK OfnHookDlgProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
  static HWND hTopDlg;

  switch(wm){
    case WM_INITDIALOG:
      OfnOrgTopDlgProc = (DLGPROC)::SetWindowLong(::GetParent(hwnd), DWL_DLGPROC, (DWORD)OfnTopDlgProc);
      break;
    case WM_DESTROY:
      if(!OfnOrgTopDlgProc)
        ::SetWindowLong(hTopDlg, DWL_DLGPROC, (DWORD)OfnOrgTopDlgProc);
      break;
  }

  return FALSE;
}
    • good
    • 0
この回答へのお礼

サンプルコードを元に作ってみたところ見事メッセージを取得することができました。これまではサブクラス化はMFCが用意している関数から使っていたので、Win32による例は大変参考になりました。

お礼日時:2009/01/05 16:27

 すんません。

どうやら私は、トンでもない大失敗をしでかしてしまった様です。私の回答は読み飛ばしてください。
    • good
    • 0

 こんにちは。

補足頂きました。

 親ダイアログの「WM_WINDOWPOSCHANGING」に送られて来ていました。
 ただ、自分自身のメッセージかファイルダイアログからのメッセージかを見分ける手立てが無いので、フラグの上げ下げ等をしないといけないかもしれません。
 因みに当方はwindows2000sp4、vc60です。以下参考程度に。

//ファイルダイアログのフックプロシージャ
UINT CALLBACK OFNHookProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
//2回親を取らないと親ダイアログに辿りつけない
HWND hParent = ::GetParent(::GetParent(hWnd));
switch(iMsg)
{
case WM_INITDIALOG:
//親ダイアログの自由データに1を書く
::SetWindowLong(hParent, GWL_USERDATA, 1);
break;

case WM_NCDESTROY:
//親ダイアログの自由データに0を書く(閉じて無くなるので)
::SetWindowLong(hParent, GWL_USERDATA, 0);
break;

case WM_SIZE://ココは一回しか呼ばれないらしい
break;
}
return 0;
}

//親ダイアログのプロシージャ
INT CALLBACK DlgProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
case WM_????????:
取り敢えずココら辺でファイルダイアログを開いていると仮定する
return 0;

case WM_WINDOWPOSCHANGING://ファイルダイアログがリサイズされる度、ココに入って来ていた
{
LPWINDOWPOS lpwp = (LPWINDOWPOS)lParam;
//ファイルダイアログが開かれていれば自由データから1の数字が取れる筈・・・
const LONG lFromFileDialog = ::GetWindowLong(lpwp->hwnd, GWL_USERDATA);
return 0;
}
case WM_NOTIFY://ココには入って来なかった
}
return 0;
}
    • good
    • 0

 こんにちは。


 OPENFILENAME構造体のFlagsメンバに、OFN_EXPLORERフラグを設定し忘れているのでは?
 OFN_ENABLEHOOKフラグ等を指定する時は、OFN_EXPLORERフラグも追加してあげないと、旧スタイル(画像上)になってしまいます。
 旧スタイルにはリサイズで摘む場所がない様です。

 ↓こんな感じに設定する
 ofn.Flags = OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_ENABLEHOOK | OFN_EXPLORER;
※添付画像が削除されました。

この回答への補足

OFN_EXPLORER属性はすでに指定しているので、別の理由があるようです。

補足日時:2008/12/29 10:05
    • good
    • 0

lpfnHook でフックしたダイアログの「親」も、ダイアログです。


この親ダイアログで、WM_SIZEイベントを受け取ることが(多分)できます。

この回答への補足

親ダイアログのWM_SIZEイベントを取得できるようにするAPIなどがあればお教え下さい。

補足日時:2008/12/29 10:06
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!