(原)CFileDlg 打开设置缩略图形式

1. 背景

调用CFileDlg打开文件选择对话框,默认是“列表”形式展示,而通常我们选择图片更好的查看方式是以“缩略图方式”来方便查看图片

这样就给我们带来麻烦,每次都需要选择“缩略图”方式来查看,所以需要重新继承一个新的类,来实现打开就显示缩略图的功能

1

2. 实现

思路1:

通过用SPY++查看该列表控件是一个SHELLDLL_DefView包含的一个SysListView32控件,想到用枚举windows窗体来获得到

HWND TRACE_FindWindow(HWND parentHwnd,HWND hAfterChild)

{

HWND hWnd = FindWindowEx(parentHwnd,hAfterChild,NULL,NULL);

if (hWnd)

{

CString str;

str.Format("parentHwnd:0x%08X,hAfterChild:0x%08X,hWnd:0x%08X\r\n",

parentHwnd,

hAfterChild,

hWnd);

OutputDebugString(str);

}

return hWnd ;

}
BOOL CMyFileDialog::OnInitDialog()

{

CFileDialog::OnInitDialog();

CWnd *parent = GetParent();

HWND hWnd1 = TRACE_FindWindow(parent->m_hWnd,NULL); //查找范围

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ComboBox

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //Static

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ToolbarWindow32

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ListBox

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //SHELLDLL_DefView //找不到??

return TRUE;

}

程序获得到的结果:

2

由此可知,可能在Initdialog函数中枚举这个控件时候,这个控件还没准备好,哪我们就自定义发送一个消息WM_POSTINITDLG,使用PostMessage,这样发送的消息会进入消息队列,windows执行完其他的消息后会执行该消息,我们在自定义消息中枚举窗体看看

BOOL CMyFileDialog::OnInitDialog()

{

CFileDialog::OnInitDialog();

//自定义消息

PostMessage(WM_POSTINITDLG,0,0);

return TRUE;

}
LRESULT CMyFileDialog::OnMYWM_POSTINIT(WPARAM wParam, LPARAM lParam)

{

//自定义消息

OutputDebugString("自定义消息中枚举窗口\r\n");

CWnd *parent = GetParent();

HWND hWnd1 = TRACE_FindWindow(parent->m_hWnd,NULL); //查找范围

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ComboBox

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //Static

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ToolbarWindow32

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ListBox

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //SHELLDLL_DefView //找到

return 1;

}

结果如下所示:

3

目前为止,我们获得到了SHELLDLL_DefView的hwnd, 可以对其发送显示缩略图消息,那我们该如何发送显示缩略图消息呢??继续我们的spy++探索,我们看看系统发送了什么消息,哪我们也相同发送一样的消息就可以了,如下图所示:

 image

我们去掉我们不关心的消息,只留下我们关心的消息,

image

点击显示的模式”缩略图”,”平铺”,”图标”等会得到一下消息记录

image

所以我们可以尝试再自定义消息中发送WM_COMMAND 给SHELLDLL_DefView,

LRESULT CMyFileDialog::OnMYWM_POSTINIT(WPARAM wParam, LPARAM lParam)

{

//自定义消息

OutputDebugString("自定义消息中枚举窗口\r\n");

CWnd *parent = GetParent();

HWND hWnd1 = TRACE_FindWindow(parent->m_hWnd,NULL); //查找范围

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ComboBox

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //Static

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ToolbarWindow32

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //ListBox

hWnd1 = TRACE_FindWindow(parent->m_hWnd,hWnd1); //SHELLDLL_DefView //找到

::SendMessage(hWnd1 ,WM_COMMAND, 0x702d,0); //就可以实现缩略图等样式

//0x702d 对应的十进制就是28717

return 1;

}

至此就可以以缩略图样式来显示

思路2:(简洁)

与思路1一致,我们可以直接获取到SHELLDLL_DefView信息,SHELLDLL_DefView的 ID 是 lst2 (值为 0x0461, 在 dlgs.h 中定义),但它不是列表框或列表控制。真正的 SysListView32 是 SHELLDLL_DefView 的 孩子,子 ID 为 1。 我们在自定义消息中获取到该控件发送消息

//enum LISTVIEWCMD

//{ ODM_VIEW_ICONS = 0x7029,

// ODM_VIEW_LIST = 0x702b,

// ODM_VIEW_DETAIL= 0x702c,

// ODM_VIEW_THUMBS= 0x702d,

// ODM_VIEW_TILES = 0x702e,

//};

BOOL CMyFileDialog::SetListView(LISTVIEWCMD cmd)

{

// Note real dialog is my parent, not me!

CWnd* pshell = GetParent()->GetDlgItem(lst2);

TRACE(_T("CMyFileDialog::SetListView: hwnd=%p\n"),pshell->GetSafeHwnd());

if (pshell) {

// SHELLDLL_DefView window found: send it the command.

pshell->SendMessage(WM_COMMAND, cmd);

return TRUE;

}

return FALSE;

}

3. 参考例子,资料

http://www.vckbase.com/index.php/wv/761

Demo:

mydlgTest.rar

CFileDlg打开设置列表框形式.pdf

原文地址:https://www.cnblogs.com/fjchenqian/p/2805025.html