hur.cn - 华软网

 热门搜索

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

  作者:未知    来源:网络    更新时间:2015/10/8
        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);
如上进行的设置,对话框资源也是按照搜到的资料进行了设置,可就是没有反映对话框进行拼接。
求大牛提点。。


---华软 网友回答---
当用GetOpenFileName或GetSaveFileName函数创建浏览器风格的Open或Save As公共对话框时,可以提供一个OFNHookProc挂钩函数。。。从CFileDialog派生的类提供OFNHookProc函数无用吗?
---华软网友回复---
看看你的  ComDlgPreviewProc
---华软网友回复---
你的对话框 要包含 一个 GroupBox (ID=1119 ; #define stc32       0x045f)用来放 原来 的 对话框
---华软网友回复---
引用 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;
}



---华软网友回复---
引用 3 楼 schlafenhamster 的回复:
你的对话框 要包含 一个 GroupBox (ID=1119 ; #define stc32       0x045f)用来放 原来 的 对话框


按你说的进行了设置,也没有效果。
我在回调函数入口处下断点,不曾断下过。
---华软网友回复---

//#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
}

---华软网友回复---
问题是你的对话框 显示了没有 ?
先把 你的对话框 搞出来。然后是:
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)

---华软网友回复---
引用 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。
两各方法我都试了下,还是不行。


---华软网友回复---
如果是 派生的:如
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);
}

---华软网友回复---
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()重写无用的吧?
---华软网友回复---
使用派生方法 , 代码 大; 不用 派生类 简单
---华软网友回复---
引用 11 楼 schlafenhamster 的回复:
使用派生方法 , 代码 大; 不用 派生类 简单


Win7下的打开对话框本身就有文件预览的功能。。
不知道你是否在Wind7下试过你的代码。。
但总之没实现打开对话框的的自定制。
---华软网友回复---
文件打开对话框,共有三个版本:
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 消息来取得所选择的文件路径,那么此时你只需要自己解析图片文件,并将其显示在你自己添加的对应的控件上面即可。
---华软网友回复---
如果你只是想在 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)) {
        ////
    }
}

---华软网友回复---
代码有些混乱,拼合的时候没改统一:
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)) {
        ////
    }
}

---华软网友回复---
引用 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)) {
        ////
    }
}


已经结贴,没法给你分了。谢谢你的解答!
---华软网友回复---
引用 16 楼 qq_26328385 的回复:
已经结贴,没法给你分了。谢谢你的解答!

这个并不重要,有这句话就够了。
---华软网友回复---
引用 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是怎么定义的?谢谢
---华软网友回复---
引用 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是怎么定义的?谢谢
你引用的这段是对的,已经没有 lpFileDlg、pfde 了。之前是因为改的时候疏忽,没有修改完全。
---华软网友回复---
你好,我个人遇到一些类似问题而不能解决,有个问题想请教下你

就是新式风格的文件对话框(你所说的第三种)不支持自定义模板了吗?!
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 消息来取得所选择的文件路径,那么此时你只需要自己解析图片文件,并将其显示在你自己添加的对应的控件上面即可。
     
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。