GetOpenFileNameのカスタムについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fji

GetOpenFileNameのカスタムについて

#1

投稿記事 by fji » 7年前

題の通りです。GetOpenFileNameをカスタムしてメモリを動的確保しようと思っているのですがうまくいきません。
//ヘッダファイル

コード:

#include <Windows.h>

class GetOpenFileDir
{
public:
	GetOpenFileDir();
	GetOpenFileDir( GetOpenFileDir& ) = delete;
	~GetOpenFileDir();
	int run( HWND hWnd );
private:
	static TCHAR* _expandMem( TCHAR* _OldString,const size_t& Size );
private:
	static UINT_PTR CALLBACK OFNHook( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
	bool          _isChoseDir;  //ディレクトリを選択するかどうか
	TCHAR*        _chosed;
	TCHAR         _chosed_s[32];
	OPENFILENAME  _ofn;         //カスタムしていく構造体
};

//ソースファイル

コード:

GetOpenFileDir::GetOpenFileDir() :
	_isChoseDir(), _chosed(), _ofn()
{
}

GetOpenFileDir::~GetOpenFileDir()
{
	free( _chosed );
	_chosed = nullptr;
}

int GetOpenFileDir::run( HWND hWnd )
{
	_ofn.lStructSize = sizeof( OPENFILENAME );
	_ofn.hwndOwner = hWnd;
	_ofn.lpstrFile = _chosed_s;
	_ofn.nMaxFile = std::size( _chosed_s );
	_ofn.Flags |= OFN_EXPLORER |       //Explorer Style
				  OFN_ENABLESIZING |   //サイズを変更できるようにする
			      OFN_ENABLEHOOK;      //フックプロシージャを使う
	_ofn.lpfnHook = OFNHook;
	_ofn.lCustData = reinterpret_cast<LPARAM>( &( *this ) );

	auto _Ret = GetOpenFileName( &_ofn );
	_ofn.lCustData = 0;

	return _Ret;
}

TCHAR* GetOpenFileDir::_expandMem( TCHAR* _OldString, const size_t& Size )
{
	return reinterpret_cast<TCHAR*>(
		( _OldString == nullptr ) ?
		calloc( Size, sizeof( TCHAR ) ) :
		_recalloc( _OldString, Size , sizeof( TCHAR ) ) );
}

UINT_PTR GetOpenFileDir::OFNHook( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch (uMsg) {
	case WM_INITDIALOG:
		return TRUE;
	case WM_NOTIFY:{
		LPOFNOTIFY lpFnNotify = reinterpret_cast<LPOFNOTIFY>( lParam );
		auto*   _This = reinterpret_cast<GetOpenFileDir*>( lpFnNotify->lpOFN->lCustData );
		switch (lpFnNotify->hdr.code) {
		case CDN_FILEOK: {
			//ファイル名を取得する
			auto _Parent = GetParent( hDlg );
			auto _Size = CommDlg_OpenSave_GetFilePath( _Parent, nullptr, 0 );
			if (_Size > std::size( _This->_chosed_s )) {
				_This->_chosed = _expandMem( _This->_chosed, _Size );
				CommDlg_OpenSave_GetFilePath( _Parent, _This->_chosed, _Size );
				ZeroMemory( _This->_chosed_s, sizeof( _This->_chosed_s ) );
			}
			return TRUE;
		}
		case CDN_FOLDERCHANGE: {
			return TRUE;
		}
		}
	}
	}

	return FALSE;
}
//呼び出し

コード:

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	GetOpenFileDir _Dir;

	_Dir.run( nullptr );

	return 0;
}
すると
Run-Time Check Failure #2 - Stack around the variable '_Dir' was corrupted.
となるのですがどこでそうなっているのかを特定できません。
どこでそうなっているのでしょう...?

かずま

Re: GetOpenFileNameのカスタムについて

#2

投稿記事 by かずま » 7年前

[ファイルを開く]ダイアログボックスが表示されたとき、
指定したファイル名は、フルパス名で何文字ですか?

それが30文字以下になるようなファイルを指定した場合にも
Run-Time Check Failure #2 になりますか?

fji

Re: GetOpenFileNameのカスタムについて

#3

投稿記事 by fji » 7年前

はい。
例えば、32文字以下のパスの場合(Ex:C:\Games\gf.f90)は_chosed_sに格納されますが
Run-Time Check Failure #2 - Stack around the variable '_Dir' was corrupted.
となります。
また、32文字以上のパスの場合(Ex:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Redist\MSVC\14.14.26405\x64\Microsoft.VC141.MFC\mfc140.dll)も同様でした。
Run-Time Check Failure #2 - Stack around the variable '_Dir' was corrupted.

返信

“C言語何でも質問掲示板” へ戻る