ファイルを開く -- コモンダイアログの「表示メニュー」を「詳細」で開く

  いろいろ探してみると...



以下のようなものでした

  
#include "stdafx.h"
#include <windows.h>
#include <commdlg.h>

UINT CALLBACK OFNHookProc(
  HWND hdlg,
  UINT uiMsg,
  WPARAM wParam,
  LPARAM lParam
)
{
	LPOFNOTIFY lpNotify;

	if ( uiMsg == WM_NOTIFY ) {
		lpNotify = (LPOFNOTIFY)lParam;
		if ( lpNotify->hdr.code == CDN_FOLDERCHANGE ) {
			HWND hTarget;
			hTarget = FindWindowEx(
				GetParent(hdlg),
				NULL,
				"SHELLDLL_DefView",
				NULL
			);
			if ( hTarget != NULL ) {
				SendMessage(
					hTarget,
					WM_COMMAND,
					MAKEWPARAM(28716,0),
					0
				);
			}
		}
	}

	return 0;
}

int main(int argc, char* argv[])
{
	OPENFILENAME ofn;

	char szBuffer[MAX_PATH];

	ZeroMemory( &ofn, sizeof( OPENFILENAME ) );

	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = NULL;
	ofn.hInstance = NULL;
	szBuffer[0] = 0x00;
	ofn.lpstrFile = szBuffer;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = 
		OFN_NOCHANGEDIR |
		OFN_HIDEREADONLY |
		OFN_EXPLORER |
		OFN_ENABLESIZING |
		OFN_ENABLEHOOK
		;
	ofn.lpfnHook = OFNHookProc;

	while( 1 ) {
		if ( GetOpenFileName( (OPENFILENAME *)&ofn ) ) {
			printf( "%s\n", szBuffer );
		}
		else {
			break;
		}
	}

	return 0;
}
  



  フックして WM_COMMAND メッセージを表示してみると



  
#include "stdafx.h"
#include <windows.h>
#include <commdlg.h>

HHOOK hhk;

LRESULT CALLBACK CallWndRetProc(
  int nCode,		// フックコード
  WPARAM wParam,	// プロセスに関するフラグ
  LPARAM lParam	// メッセージデータが入った構造体へのポインタ
)
{

	if ( nCode < 0 ) {
		return CallNextHookEx( hhk, nCode, wParam, lParam );
	}

	CWPRETSTRUCT *msg;
	char szClass[512];
	char szTitle[512];

	msg = (CWPRETSTRUCT *)lParam;
	if ( msg->message == WM_COMMAND ) {
		GetClassName( msg->hwnd, szClass, 512 );
		GetWindowText( msg->hwnd, szTitle, 512 );
		printf( "WM_COMMAND:%lX:%u:%u:%lu:%s:%s\n",
			msg->hwnd,
			LOWORD(msg->wParam),	// id
			HIWORD(msg->wParam),	// notification code
			lParam,			// handle of control
			szClass, szTitle );
	}

	return CallNextHookEx( hhk, nCode, wParam, lParam );
}

int main(int argc, char* argv[])
{
	OPENFILENAME ofn;

	char szBuffer[MAX_PATH];

	ZeroMemory( &ofn, sizeof( OPENFILENAME ) );

	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = NULL;
	ofn.hInstance = NULL;
	szBuffer[0] = 0x00;
	ofn.lpstrFile = szBuffer;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = 
		OFN_NOCHANGEDIR |
		OFN_HIDEREADONLY
		;

	hhk = SetWindowsHookEx(
		WH_CALLWNDPROCRET,
		CallWndRetProc,
		NULL,
		GetCurrentThreadId()				
	);

	while( 1 ) {
		if ( GetOpenFileName( (OPENFILENAME *)&ofn ) ) {
			printf( "%s\n", szBuffer );
		}
		else {
			break;
		}
	}

	UnhookWindowsHookEx( hhk );

	return 0;
}
  

ダイアログが開くと

  
WM_COMMAND:1402C4:1148:3:1236184:#32770:ファイルを開く
WM_COMMAND:1B0356:1148:256:1235008:ComboBox:
WM_COMMAND:130334:1148:3:1236688:ComboBoxEx32:
WM_COMMAND:1402C4:1148:10:1232936:#32770:ファイルを開く
WM_COMMAND:130334:1148:10:1233440:ComboBoxEx32:
WM_COMMAND:1402C4:1148:4:1232968:#32770:ファイルを開く
WM_COMMAND:130334:1148:4:1233472:ComboBoxEx32:
WM_COMMAND:1B0356:1148:512:1236360:ComboBox:
WM_COMMAND:1402C4:1148:3:1236204:#32770:ファイルを開く
WM_COMMAND:1B0356:1148:256:1234408:ComboBox:
WM_COMMAND:130334:1148:3:1236708:ComboBoxEx32:
WM_COMMAND:1B0356:1148:1024:1236280:ComboBox:
WM_COMMAND:1402C4:1148:5:1234564:#32770:ファイルを開く
WM_COMMAND:1B0356:1148:768:1236280:ComboBox:
  

詳細に変更すると

  
WM_COMMAND:23033A:28716:0:1234268:SHELLDLL_DefView:
WM_COMMAND:23033A:28721:0:1238008:SHELLDLL_DefView:
  




  最新の OPENFILENAME 構造体

古いタイプに比べて 12 バイト長くなっています。この長さの違いが、最新のダイアログの表示形式と関係してきます

追加されている FlagsEx は Windows2000/XP で OFN_EX_NOPLACESBAR をセットする事によって
左側の「ファイルの場所」リストを表示しないようにするものですが、古いタイプの OPENFILENAME 構造体
を使っていると、意図せずにこの「ファイルの場所」リストが表示されない場合があります。

それが、冒頭のフックをインストールした場合です。フックだけをインストールすると古いタイプのダイアログに
なってしまいます。そこで、OFN_EXPLORER フラグを追加すると新しいタイプになるのはなるのですが、
「ファイルの場所」リストは表示されずに、ダイフログも小さくなります。

この原因は、lStructSize にあります。古いタイプの OPENFILENAME 構造体のサイズは当然最新のもの
より小さいので、明示的に OFN_EXPLORER を指定すると内部でチェックされてしまうようです。これを正常に
表示するには、新しいタイプの OPENFILENAME 構造体 を使えば良いのですが、どんな場合でもうまくいきそう
な方法をつい考えてしまいます

  
typedef struct tagOFN { 
  DWORD         lStructSize; 
  HWND          hwndOwner; 
  HINSTANCE     hInstance; 
  LPCTSTR       lpstrFilter; 
  LPTSTR        lpstrCustomFilter; 
  DWORD         nMaxCustFilter; 
  DWORD         nFilterIndex; 
  LPTSTR        lpstrFile; 
  DWORD         nMaxFile; 
  LPTSTR        lpstrFileTitle; 
  DWORD         nMaxFileTitle; 
  LPCTSTR       lpstrInitialDir; 
  LPCTSTR       lpstrTitle; 
  DWORD         Flags; 
  WORD          nFileOffset; 
  WORD          nFileExtension; 
  LPCTSTR       lpstrDefExt; 
  LPARAM        lCustData; 
  LPOFNHOOKPROC lpfnHook; 
  LPCTSTR       lpTemplateName; 
#if (_WIN32_WINNT >= 0x0500)
  void *        pvReserved;
  DWORD         dwReserved;
  DWORD         FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAME, *LPOPENFILENAME
  



  で、改造版

  
#include "stdafx.h"
#include <windows.h>
#include <commdlg.h>

UINT CALLBACK OFNHookProc(
  HWND hdlg,
  UINT uiMsg,
  WPARAM wParam,
  LPARAM lParam
)
{
	LPOFNOTIFY lpNotify;

	if ( uiMsg == WM_NOTIFY ) {
		lpNotify = (LPOFNOTIFY)lParam;
		if ( lpNotify->hdr.code == CDN_FOLDERCHANGE ) {
			HWND hTarget;
			hTarget = FindWindowEx(
				GetParent(hdlg),
				NULL,
				"SHELLDLL_DefView",
				NULL
			);
			if ( hTarget != NULL ) {
				SendMessage(
					hTarget,
					WM_COMMAND,
					MAKEWPARAM(28716,0),
					0
				);
			}
		}
	}

	return 0;
}

typedef struct tagOFNOLD {
    DWORD         lStructSize; 
    HWND          hwndOwner; 
    HINSTANCE     hInstance; 
    LPCTSTR       lpstrFilter; 
    LPTSTR        lpstrCustomFilter; 
    DWORD         nMaxCustFilter; 
    DWORD         nFilterIndex; 
    LPTSTR        lpstrFile; 
    DWORD         nMaxFile; 
    LPTSTR        lpstrFileTitle; 
    DWORD         nMaxFileTitle; 
    LPCTSTR       lpstrInitialDir; 
    LPCTSTR       lpstrTitle; 
    DWORD         Flags; 
    WORD          nFileOffset; 
    WORD          nFileExtension; 
    LPCTSTR       lpstrDefExt; 
    DWORD         lCustData; 
    LPOFNHOOKPROC lpfnHook; 
    LPCTSTR       lpTemplateName; 
} OPENFILENAMEOLD; 

int main(int argc, char* argv[])
{
	OPENFILENAME *ofn;
	char *szOfn = new char[sizeof(OPENFILENAME)+12];
	ofn = (OPENFILENAME *)szOfn;

	char szBuffer[MAX_PATH];

	ZeroMemory( ofn, sizeof( OPENFILENAME )+12 );

	ofn->lStructSize = sizeof(OPENFILENAME);

	OSVERSIONINFO ovinfo;
	ovinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx( &ovinfo );
	if ( ovinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) {
		if ( ovinfo.dwMajorVersion >= 5 ) {
			if ( sizeof(OPENFILENAMEOLD) == sizeof(OPENFILENAME) ) {
				ofn->lStructSize = sizeof(OPENFILENAME)+12;
			}
		}
	}

	ofn->hwndOwner = NULL;
	ofn->hInstance = NULL;
	szBuffer[0] = 0x00;
	ofn->lpstrFile = szBuffer;
	ofn->nMaxFile = MAX_PATH;
	ofn->Flags = 
		OFN_NOCHANGEDIR |
		OFN_HIDEREADONLY |
		OFN_EXPLORER |
		OFN_ENABLESIZING |
		OFN_ENABLEHOOK
		;
	ofn->lpfnHook = OFNHookProc;

	while( 1 ) {
		if ( GetOpenFileName( ofn ) ) {
			printf( "%s\n", szBuffer );
		}
		else {
			break;
		}
	}

	delete [] szOfn;
	return 0;
}
 
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ