Win7实现对话框预览功能,OPENFILENAME如何设置?求帮忙!!

奋起无痕 2015-10-08 03:45:24
m_ofn.Flags |= OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_HIDEREADONLY ;
m_ofn.lpstrTitle = _T("打开图片预览对话框");
m_ofn.hInstance = AfxGetInstanceHandle();
m_ofn.lpstrFilter = _T(".JPG .JPEG\0*.jpg;*.jpeg\0.STL\0*.stl\0所有文件 \0 *.*\0 ");
m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG_HOOK);
m_ofn.lpfnHook = (LPOFNHOOKPROC)ComDlgPreviewProc;
m_ofn.lStructSize = sizeof(OPENFILENAME);
如上进行的设置,对话框资源也是按照搜到的资料进行了设置,可就是没有反映对话框进行拼接。
求大牛提点。。

...全文
331 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
幻夢之葉 2015-12-01
  • 打赏
  • 举报
回复
你好,我个人遇到一些类似问题而不能解决,有个问题想请教下你 就是新式风格的文件对话框(你所说的第三种)不支持自定义模板了吗?! http://bbs.csdn.net/topics/391868602 以上是我的问题贴,我原本打算实在解决不了,就用新式风格文件对话框中自定义模板的,想确认下以上的疑问! 期望得到你的解答,感激不尽!
引用 13 楼 SXJIAKE 的回复:
文件打开对话框,共有三个版本: 1. Windows 98 时代,打开对话框没有侧边栏,大小不可调整。 2. Windows XP 时代,包含侧边栏,大小可以调整: 3. Windows Vista 开始,新式打开文件对话框: 然而第二种对话框风格在 Windows Vista 开始通过参数是无法调出来的,只能通过对话框模版。 对于内置的文件打开对话框,Windows SDK 的 include 目录包括这两个文件: fileopen.dlg - 常用的几种对话框模版 dlgs.h - 相关的控件 ID 定义 包括几种内置的打开对话框模版。虽然说打开对话框可以自定义对话框,但仅限于上面的前两种。而第三种,以我目前的了解,根本不支持对话框定义的,毕竟其中有些 DirectUI 窗口。如果要自己在对话框上添加预览,必然是上面第二种对话框。 对于消息的处理,OFNHookProc 这个回调函数可以通过 WM_NOTIFY 发送很多通知,包括 CDN_SELCHANGE。上面的也提到了,这个通知消息是当选择文件时可以收到的,可以使用 CDM_GETFILEPATH 消息来取得所选择的文件路径,那么此时你只需要自己解析图片文件,并将其显示在你自己添加的对应的控件上面即可。
「已注销」 2015-10-19
  • 打赏
  • 举报
回复
引用 18 楼 lanzai10 的回复:
[quote=引用 15 楼 SXJIAKE 的回复:] 代码有些混乱,拼合的时候没改统一:
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (hr == S_OK) {
    DWORD fdlgopts;
    hr = pfd->GetOptions(&fdlgopts);
    if (hr == S_OK) {
        // 强制开启预览面板
        hr = pfd->SetOptions(fdlgopts | FOS_FORCEPREVIEWPANEON);
    }
    if (hr == S_OK) {
        hr = pfd->Show(NULL);
        if (hr == S_OK) {
            IShellItem *pshi;
            hr = pfd->GetResult(&pshi);
            if (hr == S_OK) {
                PWSTR pszFilePath = NULL;
                hr = pshi->GetDisplayName(SIGDN_FILESYSPATH,  &pszFilePath);
                if (hr == S_OK) {
                    ////
                    CoTaskMemFree(pszFilePath);
                }
                pshi->Release();
            }
        }
    }
    pfd->Release();
} else {
    OPENFILENAME ofn = { 0 };
    ////
    if (GetOpenFileName(&ofn)) {
        ////
    }
}
你好,请问lpFileDlg、pfde是怎么定义的?谢谢[/quote]你引用的这段是对的,已经没有 lpFileDlg、pfde 了。之前是因为改的时候疏忽,没有修改完全。
lanzai10 2015-10-18
  • 打赏
  • 举报
回复
引用 15 楼 SXJIAKE 的回复:
代码有些混乱,拼合的时候没改统一:
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (hr == S_OK) {
    DWORD fdlgopts;
    hr = pfd->GetOptions(&fdlgopts);
    if (hr == S_OK) {
        // 强制开启预览面板
        hr = pfd->SetOptions(fdlgopts | FOS_FORCEPREVIEWPANEON);
    }
    if (hr == S_OK) {
        hr = pfd->Show(NULL);
        if (hr == S_OK) {
            IShellItem *pshi;
            hr = pfd->GetResult(&pshi);
            if (hr == S_OK) {
                PWSTR pszFilePath = NULL;
                hr = pshi->GetDisplayName(SIGDN_FILESYSPATH,  &pszFilePath);
                if (hr == S_OK) {
                    ////
                    CoTaskMemFree(pszFilePath);
                }
                pshi->Release();
            }
        }
    }
    pfd->Release();
} else {
    OPENFILENAME ofn = { 0 };
    ////
    if (GetOpenFileName(&ofn)) {
        ////
    }
}
你好,请问lpFileDlg、pfde是怎么定义的?谢谢
「已注销」 2015-10-10
  • 打赏
  • 举报
回复
引用 16 楼 qq_26328385 的回复:
已经结贴,没法给你分了。谢谢你的解答!
这个并不重要,有这句话就够了。
schlafenhamster 2015-10-09
  • 打赏
  • 举报
回复
如果是 派生的:如 class CExpFileOpen : public CFileDialog

BOOL CExpFileOpen::OnInitDialog() 
{
	CFileDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	GetDlgItem(IDC_STATIC_TXT)->SetWindowText("Show you how to put it in !");
//
	CFileDialog *Parent=(CFileDialog*)GetParent();// not GWL_WNDPROC
	WNDPROC OldDlgProc = (WNDPROC)SetWindowLong(Parent->m_hWnd, DWL_DLGPROC, (LONG)NewDlgProc); 
// save it in window
	::SetProp(Parent->m_hWnd,"ExpFileOpen",(HANDLE)OldDlgProc);
//
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

LRESULT CALLBACK NewDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) //子类化过程 
{ 
	LPHELPINFO lphi;
	switch(Msg) 
	{  
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
			case IDOK:
				afxDump << " OK\n";
			break;
			case IDCANCEL:
				afxDump << " CANCEL\n";
			break;
			default:
				afxDump << LOWORD(wParam) << " =ID\n";
		}
		break;
	case WM_SYSCOMMAND:
		wParam &= 0xFFFF;
		switch (wParam)
		{
			case SC_CLOSE:
				afxDump << "Close\n";
				break;
			case SC_CONTEXTHELP:
				afxDump << "Help\n";
				break;//return 1;//
		}
		break;
	case WM_HELP:
		lphi = (LPHELPINFO) lParam;
		afxDump << lphi->iCtrlId << "  Help\n";
		break;

	}
	return CallWindowProc((WNDPROC)::GetProp(hWnd,"ExpFileOpen"), hWnd, Msg, wParam, lParam);
}
奋起无痕 2015-10-09
  • 打赏
  • 举报
回复
引用 7 楼 schlafenhamster 的回复:
问题是你的对话框 显示了没有 ? 先把 你的对话框 搞出来。然后是: fd.m_ofn.Flags|=OFN_EXPLORER; // default by Afx // fd.m_ofn.Flags|=OFN_ENABLEHOOK;// default by Afx fd.m_ofn.lpfnHook=DNHookProc;//="_AfxCommDlgProc" see"dlgcomm.cpp" <>NULL! //UINT CALLBACK _AfxCommDlgProc(HWND hWnd,UINT message, // WPARAM wParam,LPARAM lParam); UINT CALLBACK DNHookProc(HWND hDlg,UINT uMsg,WPARAM wPar,LPARAM lPar)
对话框一直没有显示出来。 对话框的属性设置成 'Clip siblings' 'Child' 'None' '3Dlook' 'Control' 'Visible'的。 有文章说是加个StaticText控件,ID设成1119。 两各方法我都试了下,还是不行。
schlafenhamster 2015-10-09
  • 打赏
  • 举报
回复
问题是你的对话框 显示了没有 ? 先把 你的对话框 搞出来。然后是: fd.m_ofn.Flags|=OFN_EXPLORER; // default by Afx // fd.m_ofn.Flags|=OFN_ENABLEHOOK;// default by Afx fd.m_ofn.lpfnHook=DNHookProc;//="_AfxCommDlgProc" see"dlgcomm.cpp" <>NULL! //UINT CALLBACK _AfxCommDlgProc(HWND hWnd,UINT message, // WPARAM wParam,LPARAM lParam); UINT CALLBACK DNHookProc(HWND hDlg,UINT uMsg,WPARAM wPar,LPARAM lPar)
schlafenhamster 2015-10-09
  • 打赏
  • 举报
回复

//#define NO_TEMP
void CMyFileOpenDlg::OnButtonNew() 
{
	// TODO: Add your control notification handler code here
	char fileName[MAX_PATH]="";
#ifndef NO_TEMP
	CExpFileOpen dlgFile(TRUE); 
#else
	CFileDialog dlgFile(TRUE);
#endif
//if use new style!
	OSVERSIONINFO VersionInformation;   
	GetVersionEx(&VersionInformation);
	if(VersionInformation.dwMajorVersion >= 5)
		dlgFile.m_ofn.lStructSize=88;// new =88
	else
		dlgFile.m_ofn.lStructSize=76;// old =76
#ifndef NO_TEMP
	dlgFile.m_ofn.Flags |= OFN_ENABLETEMPLATE;// add our temp !
	dlgFile.m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EX_OPEN); //=1547!
	dlgFile.m_ofn.hInstance=AfxGetInstanceHandle(); 
#endif
	dlgFile.m_ofn.lpstrTitle = "Explorer Style Open File"; 
	dlgFile.m_ofn.lpstrFile = fileName; 
	dlgFile.m_ofn.Flags |= OFN_EXPLORER;
//'Clip siblings' 'Child' 'None' '3Dlook' 'Control' 'Visible'
	dlgFile.m_ofn.lpstrFilter="Any file(*.*)\0*.*\0";
	dlgFile.m_ofn.lpstrDefExt = "txt"; 
// show 
	dlgFile.DoModal();
#ifdef _DEBUG
	afxDump << fileName << " \n";
#endif
}
奋起无痕 2015-10-09
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
你的对话框 要包含 一个 GroupBox (ID=1119 ; #define stc32 0x045f)用来放 原来 的 对话框
按你说的进行了设置,也没有效果。 我在回调函数入口处下断点,不曾断下过。
奋起无痕 2015-10-09
  • 打赏
  • 举报
回复
引用 2 楼 schlafenhamster 的回复:
看看你的 ComDlgPreviewProc
UINT_PTR CALLBACK ComDlgPreviewProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: //初始化对话框上的控件 if(SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETCHECK,0,0) == BST_UNCHECKED) { HWND hWnd; hWnd = GetDlgItem(hDlg, IDC_PIC); ::SetWindowText(hWnd, "\n\n\n\n 点击图象文件进行预览!"); } break; case WM_DESTROY: //消毁对话框 { LPOPENFILENAME lpOFN = (LPOPENFILENAME)GetWindowLong(hDlg, DWL_USER); } break; case WM_COMMAND: //这里处理,IDC_CHECK1命令 if ((HIWORD(wParam) == BN_CLICKED) && (LOWORD(wParam) == IDC_CHECK1)) { if(SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETCHECK, 0, 0) == BST_CHECKED) { InvalidateRect(GetDlgItem(hDlg, IDC_PIC), NULL, FALSE); ::SetDlgItemInt(hDlg, IDC_W, 0, FALSE); ::SetDlgItemInt(hDlg, IDC_H, 0, FALSE); } } //不选中, if(SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETCHECK,0,0) == BST_UNCHECKED) { HWND hWnd; hWnd = GetDlgItem(hDlg, IDC_PIC); ::SetWindowText(hWnd, "\n\n\n\n 点击图象文件进行预览!"); } //选中 if(SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETCHECK,0,0) != BST_UNCHECKED) { HWND hWnd; hWnd = GetDlgItem(hDlg, IDC_PIC); ::SetWindowText(hWnd, "\n\n\n\n 处于非预览状态!"); } if(LOWORD(wParam) == IDOK) { } break; case WM_NOTIFY: HandleNotify(hDlg, (LPOFNOTIFY)lParam); default: return FALSE; } return TRUE; }
奋起无痕 2015-10-09
  • 打赏
  • 举报
回复
引用 14 楼 SXJIAKE 的回复:
如果你只是想在 Windows Vista 以上的文件打开对话框中开启预览面板,建议你用 COM 的方法,而不是去调用新式的文件打开对话框:
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (hr == S_OK) {
    DWORD fdlgopts;
    hr = lpFileDlg->GetOptions(&fdlgopts);
    if (hr == S_OK) {
        // 强制开启预览面板
        lpFileDlg->SetOptions(fdlgopts | FOS_FORCEPREVIEWPANEON);
    }
    hr = pfd->Show(NULL);
    if (hr == S_OK) {
        IShellItem *pshi;
        hr = pfd->GetResult(&pshi);
        if (hr == S_OK) {
            PWSTR pszFilePath = NULL;
            hr = pshi->GetDisplayName(SIGDN_FILESYSPATH,  &pszFilePath);
            if (hr == S_OK) {
                ////
                CoTaskMemFree(pszFilePath);
            }
            pshi->Release();
        }
        pfde->Release();
    }
    pfd->Release();
} else {
    OPENFILENAME ofn = { 0 };
    ////
    if (GetOpenFileName(&ofn)) {
        ////
    }
}
已经结贴,没法给你分了。谢谢你的解答!
「已注销」 2015-10-09
  • 打赏
  • 举报
回复
代码有些混乱,拼合的时候没改统一:
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (hr == S_OK) {
    DWORD fdlgopts;
    hr = pfd->GetOptions(&fdlgopts);
    if (hr == S_OK) {
        // 强制开启预览面板
        hr = pfd->SetOptions(fdlgopts | FOS_FORCEPREVIEWPANEON);
    }
    if (hr == S_OK) {
        hr = pfd->Show(NULL);
        if (hr == S_OK) {
            IShellItem *pshi;
            hr = pfd->GetResult(&pshi);
            if (hr == S_OK) {
                PWSTR pszFilePath = NULL;
                hr = pshi->GetDisplayName(SIGDN_FILESYSPATH,  &pszFilePath);
                if (hr == S_OK) {
                    ////
                    CoTaskMemFree(pszFilePath);
                }
                pshi->Release();
            }
        }
    }
    pfd->Release();
} else {
    OPENFILENAME ofn = { 0 };
    ////
    if (GetOpenFileName(&ofn)) {
        ////
    }
}
「已注销」 2015-10-09
  • 打赏
  • 举报
回复
如果你只是想在 Windows Vista 以上的文件打开对话框中开启预览面板,建议你用 COM 的方法,而不是去调用新式的文件打开对话框:
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
if (hr == S_OK) {
    DWORD fdlgopts;
    hr = lpFileDlg->GetOptions(&fdlgopts);
    if (hr == S_OK) {
        // 强制开启预览面板
        lpFileDlg->SetOptions(fdlgopts | FOS_FORCEPREVIEWPANEON);
    }
    hr = pfd->Show(NULL);
    if (hr == S_OK) {
        IShellItem *pshi;
        hr = pfd->GetResult(&pshi);
        if (hr == S_OK) {
            PWSTR pszFilePath = NULL;
            hr = pshi->GetDisplayName(SIGDN_FILESYSPATH,  &pszFilePath);
            if (hr == S_OK) {
                ////
                CoTaskMemFree(pszFilePath);
            }
            pshi->Release();
        }
        pfde->Release();
    }
    pfd->Release();
} else {
    OPENFILENAME ofn = { 0 };
    ////
    if (GetOpenFileName(&ofn)) {
        ////
    }
}
「已注销」 2015-10-09
  • 打赏
  • 举报
回复
文件打开对话框,共有三个版本:
1. Windows 98 时代,打开对话框没有侧边栏,大小不可调整。

2. Windows XP 时代,包含侧边栏,大小可以调整:

3. Windows Vista 开始,新式打开文件对话框:

然而第二种对话框风格在 Windows Vista 开始通过参数是无法调出来的,只能通过对话框模版。

对于内置的文件打开对话框,Windows SDK 的 include 目录包括这两个文件:
fileopen.dlg - 常用的几种对话框模版
dlgs.h - 相关的控件 ID 定义
包括几种内置的打开对话框模版。虽然说打开对话框可以自定义对话框,但仅限于上面的前两种。而第三种,以我目前的了解,根本不支持对话框定义的,毕竟其中有些 DirectUI 窗口。如果要自己在对话框上添加预览,必然是上面第二种对话框。

对于消息的处理,OFNHookProc 这个回调函数可以通过 WM_NOTIFY 发送很多通知,包括 CDN_SELCHANGE。上面的也提到了,这个通知消息是当选择文件时可以收到的,可以使用 CDM_GETFILEPATH 消息来取得所选择的文件路径,那么此时你只需要自己解析图片文件,并将其显示在你自己添加的对应的控件上面即可。
奋起无痕 2015-10-09
  • 打赏
  • 举报
回复
引用 11 楼 schlafenhamster 的回复:
使用派生方法 , 代码 大; 不用 派生类 简单
Win7下的打开对话框本身就有文件预览的功能。。 不知道你是否在Wind7下试过你的代码。。 但总之没实现打开对话框的的自定制。
schlafenhamster 2015-10-09
  • 打赏
  • 举报
回复
使用派生方法 , 代码 大; 不用 派生类 简单
奋起无痕 2015-10-09
  • 打赏
  • 举报
回复
[quote=引用 9 楼 schlafenhamster 的回复:] 如果是 派生的:如 class CExpFileOpen : public CFileDialog [code=c] BOOL CExpFileOpen::OnInitDialog() 可覆盖的函数 OnShareViolation发生共享冲突时调用 OnFileNameOK确认键入对话框中的文件名 OnLBSelChangedNotify当列表框选择改变时调用 OnInitDone处理WM_NOTIFY CDN_INITDONE消息 OnFileNameChange处理WM_NOTIFY CDN_SELCHANGE消息 OnFolderChange处理WM_NOTIFY CDN_FOLDERCHANGE消息 OnTypeChange处理WM_NOTIFY CDN_TYPECHANGE消息 OnInitDialog()重写无用的吧?
schlafenhamster 2015-10-08
  • 打赏
  • 举报
回复
你的对话框 要包含 一个 GroupBox (ID=1119 ; #define stc32 0x045f)用来放 原来 的 对话框
schlafenhamster 2015-10-08
  • 打赏
  • 举报
回复
看看你的 ComDlgPreviewProc
奋起无痕 2015-10-08
  • 打赏
  • 举报
回复
当用GetOpenFileName或GetSaveFileName函数创建浏览器风格的Open或Save As公共对话框时,可以提供一个OFNHookProc挂钩函数。。。从CFileDialog派生的类提供OFNHookProc函数无用吗?

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧