• (原)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

  • 相关阅读:
    webstorm & phpstorm破解
    JSON和JSONP
    angular.extend(dst, src)对象拓展
    angular.foreach 循环方法使用指南
    angular 指令@、=、&的用法和区别
    angular directive指令相互独立
    angular directive指令的复用
    对apply和call的理解
    图片上传
    vue 路由缓存
  • 原文地址:https://www.cnblogs.com/fjchenqian/p/2805025.html
Copyright © 2020-2023  润新知