Поиск:

Ответ в темуСоздание новой темы Создание опроса
> CFileDialog, не вызывается OnLBSelChangedNotify 
V
    Опции темы
0x07L
Дата 23.8.2006, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 10.6.2006
Где: Москва

Репутация: 1
Всего: 5



В моем классе, производном от CFileDialog, не вызывается виртуальная функция CFileDialog::OnLBSelChangedNotify. Как я выяснил, функции _AfxCommDlgProc (файл dlgcomm.cpp), которую CFileDialog подставляет в качестве хука, просто не приходит соответствующее сообщение. Немного об OnLBSelChangedNotify:

CFileDialog::OnLBSelChangedNotify

This function is called whenever the current selection in a list box is about to change.
 
virtual void OnLBSelChangedNotify(
   UINT nIDBox,
   UINT iCurSel,
   UINT nCode
);

Parameters
. . .

Remarks
Override this function to provide custom handling of selection changes in the list box. For example, you can use this function to display the access rights or date-last-modified of each file the user selects.


Вот кусочек функции _AfxCommDlgProc:
Код

if (message == WM_INITDIALOG)
    {
        _afxMsgLBSELCHANGE = ::RegisterWindowMessage(LBSELCHSTRING);
         // . . .
    }
// . . .
if (message == _afxMsgLBSELCHANGE)
    {
// Вот сюда мы почему-то никогда не попадаем
        ASSERT_KINDOF(CFileDialog, pDlg);
        ((CFileDialog*)pDlg)->OnLBSelChangedNotify((UINT)wParam, LOWORD(lParam),
                HIWORD(lParam));
        return 0;
    }

Флажок что-ли ему какой-то нужен? Но, во-первых, такого флажка в MSDN я не нашел. Во-вторых, об этом должен заботится не я, а CFileDialog. Кто-нибудь сталкивался с этим? Как всегда, тестовая программка:
Код

#include "stdafx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

///////////////////////////////////////
// CMyFileDialog

class CMyFileDialog : public CFileDialog
{
    DECLARE_DYNAMIC(CMyFileDialog)

public:

    CMyFileDialog(
        BOOL bOpenFileDialog,
        LPCTSTR lpszDefExt = NULL,
        LPCTSTR lpszFileName = NULL,
        DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
        LPCTSTR lpszFilter = NULL,
        CWnd* pParentWnd = NULL)
    : CFileDialog(
        bOpenFileDialog,
        lpszDefExt, 
        lpszFileName,
        dwFlags,
        lpszFilter,
        pParentWnd) {}

    virtual ~CMyFileDialog() {}

protected:
    
    void OnLBSelChangeNotify(UINT box, UINT sel, UINT code)
    {
        Beep(1600, 40);
        CFileDialog::OnLBSelChangedNotify(box, sel, code);
    }
};

IMPLEMENT_DYNAMIC(CMyFileDialog, CFileDialog)

///////////////////////////////////////
// CApplication

class CApplication : public CWinApp
{
public:

    CApplication() : CWinApp() {}
    ~CApplication() {}

    virtual BOOL InitInstance()
    {
        INITCOMMONCONTROLSEX icc = {sizeof icc, ICC_WIN95_CLASSES};
        InitCommonControlsEx(&icc);

        CWinApp::InitInstance();

        CMyFileDialog dlg (TRUE, 0, 0,
             OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT);
        m_pMainWnd = &dlg;
        dlg.DoModal();

        // Since the dialog has been closed, return FALSE so that we exit the
        // application, rather than start the application's message pump.
        return FALSE;
    }
};

// The one and only CApplication object
CApplication app;


Это сообщение отредактировал(а) 0x07L - 23.8.2006, 10:56

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  CFileDialog___OnLBSelChangeNotify.zip 86,00 Kb
PM MAIL   Вверх
Earnest
Дата 23.8.2006, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Вот еще кусочек _AfxCommDlgProc (ДО обработки сообщений)

Код

    if (pDlg->IsKindOf(RUNTIME_CLASS(CFileDialog)))
    {
        // If we're exploring then we are not interested in the Registered messages
        if (((CFileDialog*)pDlg)->m_ofn.Flags & OFN_EXPLORER)
            return 0;
    }



--------------------
...
PM   Вверх
0x07L
Дата 23.8.2006, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 10.6.2006
Где: Москва

Репутация: 1
Всего: 5



Ха, в функцию хука вообще не приходят зарегистрированные сообщения! Зато приходит WM_SETREDRAW... Мы не проходим дальше
Код

if (message < 0xC000)
{
    // not a ::RegisterWindowMessage message
    return 0;
}

Что такое?
PM MAIL   Вверх
Earnest
Дата 23.8.2006, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



0x07L, у тебя стиль OFN_EXPLORER? 
// If we're exploring then we are not interested in the Registered messages

Добавлено @ 16:55 
Там другие уведомления приходят:
Цитата

The CDN_SELCHANGE notification message is sent by an Explorer-style Open or Save As dialog box when the selection changes in the list box that displays the contents of the currently opened folder or directory. 

Your OFNHookProc hook procedure receives this message in the form of a WM_NOTIFY message. 


Добавлено @ 16:57 
А дальше - вызываются виртуальные функции OnFileNameChange, OnFolderChange, OnTypeChange.


--------------------
...
PM   Вверх
0x07L
Дата 23.8.2006, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 10.6.2006
Где: Москва

Репутация: 1
Всего: 5



Стиль OFN_EXPLORER устанавливает сам CFileDialog. 

Ну я же пробовал днем OnFileNameChange, он приходил, оставалось только найти окно ListView, который отображает файлы. Вот тут-то я и сплоховал. Посмотрел его свойства в Spy, увидел там идентификатор 1, подивился немного тому, что это IDOK и что в диалоге есть кнопка с таким ID, но не обратил на это внимание. Все попытки найти это окно были неудачными и я это дело бросил. А стоило то всего-то посмотреть в окно windows Spy++. Оказывается, это окно - не прямой потомок диалога...

Конечно, удобнее использовать флажки, которые передаются в OnLBSelChange, но что делать, если OnLBSelChange не вызывается. В общем, проблема решена. Однако ради любопытства стоит узнать, почему в MSDN написано не то, что происходит на самом деле. А в тот if-блок, который Вы привели, мы тоже не попадаем, поскольку
Код

if (message < 0xC000)
{
    // not a ::RegisterWindowMessage message
    return 0;
}


Это сообщение отредактировал(а) 0x07L - 24.8.2006, 07:03
PM MAIL   Вверх
Earnest
Дата 24.8.2006, 07:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(0x07L @  23.8.2006,  20:07 Найти цитируемый пост)
А в тот if-блок, который Вы привели, мы тоже не попадаем

Да? Ну, возможно, это MS-программисты перестарались...
Но суть в том, что сначала в API был FileDialog, который выглядел немного по-другому (попроще), и документация была написана для него. А потом появился дополнительный стиль эксплорер: это совсем другое окно с совсем другим механизмом уведомлений, который работает через NOTIFY, как common-контролы. Новую документацию написали, а в старой написать, что это только для старого стиля, видимо, забыли. Но если почитать про новые уведомления, то все становится понятным.



--------------------
...
PM   Вверх
0x07L
Дата 24.8.2006, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 10.6.2006
Где: Москва

Репутация: 1
Всего: 5



Да, наверное, очень сложно поддерживать MSDN в актуальном состоянии.
Только вот зачем устанавливать процедуру хука для диалога открытия / сохранения файлов, раз она ничего, выходит, не делает.
PM MAIL   Вверх
Earnest
Дата 24.8.2006, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Да ведь процедура-то на все common-диалоги общая, и там кое-что делается для случая стиля "эксплорер": см. самое начало, про pThreadState->m_pAlternateWndInit. Это как раз CFileDialog сабклассится.
Не самое изящное решение, конечно. Больше напоминает костыль. Ну да такова реальная жизнь кода: в любом "долгом" приложении можно встретить такие костыли.


--------------------
...
PM   Вверх
0x07L
Дата 24.8.2006, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 10.6.2006
Где: Москва

Репутация: 1
Всего: 5



Earnest, большое спасибо за помощь!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.3892 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.