Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
5 / 5 / 2
Регистрация: 03.05.2016
Сообщений: 221

В MFC приложении не загружается положение тулбаров из предыдущей сессии

23.07.2022, 12:00. Показов 2789. Ответов 9
Метки c++, mfc (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Досталось в наследство приложение написанное с помощью МFC.
Так же с помощью мастера приложений создал тестовое приложение.
Сравниваю эти приложения, вроде одинаково отнаследованы от CWinAppEx (в файлах с именем приложения),
но почему то не удаётся загрузить положение тулбаров для старого (полученного от коллеги) приложения.
С проблемами записи статуса я разобрался - ранее коллега отключил свойство m_bSaveState = FALSE.
Состояние тулбаров я запоминаю в реестре при закрытии приложения (например для тулбара m_MeasurementToolBar) с помощью кода m_MeasurementToolBar.SaveState(_T("SOFTW ARE\\Test1\\Test2\\Workspace\")).
Соответственно в файле приложения есть установка ключа SetRegistryKey(_T("Test1")) и SetRegistryBase(_T("Test2")).
Сам коллега не может сказать, что делал с приложением (иначе у него бы спросил), после каких изменений перестал загружаться статус тулбаров.

Собственно вопрос: как можно загрузить состояние тулбара (его расположение в окне) из реестра, или почему оно может не загружаться?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.07.2022, 12:00
Ответы с готовыми решениями:

Сохранение положения тулбаров из предыдущей сессии пользователя
Пишу приложение на MFC. Пользователь может поменять положение тулбаров, выйти из приложения, при повторном входе в приложение, положение...

Удаление предыдущей сессии при открывании приложении во второй вкладке
Добрый день, Каким образом можно реализовать удаление предыдущей сессии, если приложение было открыто во второй вкладке. Пробовал: ...

Сохранение положения тулбаров из прошлой сессии
Здравствуйте! Пишу приложение на с++ для windows. Пытаюсь выполнить сохранение сессии приложения автоматически, т.е. когда флаг...

9
фрилансер
 Аватар для Алексей1153
6466 / 5688 / 1131
Регистрация: 11.10.2019
Сообщений: 15,138
23.07.2022, 14:52
MaximSergeevith, а сохранённый дамп в реестре от тестового приложения и от боевого - одинаковые ? (конечно, если тестовый набор плашек такой же)
0
5 / 5 / 2
Регистрация: 03.05.2016
Сообщений: 221
23.07.2022, 16:43  [ТС]
Там разный набор плашек. Какие то коллега создавал сам. На картинках моё приложение - это где Test1 & Test2,
То, что для образца - в папке \MFC\Samples\StateCollection
Миниатюры
В MFC приложении не загружается положение тулбаров из предыдущей сессии   В MFC приложении не загружается положение тулбаров из предыдущей сессии  
0
фрилансер
 Аватар для Алексей1153
6466 / 5688 / 1131
Регистрация: 11.10.2019
Сообщений: 15,138
23.07.2022, 19:35
MaximSergeevith, попробуй "вручную" (с помощью тестовых кнопок) повызывать CWinAppEx::SaveState/CWinAppEx::LoadState
понаблюдай, что появляется в реестре
и возвращают ли функции ошибку
0
5 / 5 / 2
Регистрация: 03.05.2016
Сообщений: 221
23.07.2022, 20:27  [ТС]
В этом то и проблема, есть тулбары (их создавал коллега), при сохранении которых вылетает ошибка сериализации.
Поэтому я хотел сохранять положение тех, что ошибок не вызывают и загружать их координаты из реестра - как это сделать?
0
фрилансер
 Аватар для Алексей1153
6466 / 5688 / 1131
Регистрация: 11.10.2019
Сообщений: 15,138
23.07.2022, 20:43
MaximSergeevith, если честно, я не занимался никогда этими сохранениями тулбаров, поэтому точно не смогу подсказать.

Я бы для начала выяснил, что именно глючит. Делаем тестовую GIT ветку проекта. Удаляем половину элементов с тулбаров. Пробуем. И так до выяснения, какой именно элемент вызывает проблему

к слову, а GIT-репозиторий проекта не вёлся ? Можно было бы найти коммит, где появился глюк

Добавлено через 45 секунд
Цитата Сообщение от MaximSergeevith Посмотреть сообщение
при сохранении которых вылетает ошибка сериализации.
как именно эта ошибка проявляется ? Если запустить на отладку - что ловится ?
0
5 / 5 / 2
Регистрация: 03.05.2016
Сообщений: 221
24.07.2022, 01:07  [ТС]
Git репозиторий - 13 лет назад таких слов эти люди не слышали Проект архивироваться начал после глобальных правок в приложении.
Что именно глючит - причина в том, как эти тулары создаются, с этим ещё разбираться надо, но кое какие скользкие места я выявил непример в следующем:

C++
1
2
3
4
5
6
7
8
9
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
    // базовый класс не работает
 
    if (!CMDIFrameWndEx::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
    {
        return FALSE;
    }
}
вместо

C++
1
2
3
4
5
6
7
8
9
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
    // базовый класс не работает
 
    if (!CMDIFrameWnd::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
    {
        return FALSE;
    }
}
По этой причине с ошибкой сохраняется статус m_wndMenuBar (объект CMFCMenuBar).

Далее один из тулбаров при создании использует код

C++
1
2
3
4
5
6
7
8
9
10
if(!reload)
    {
        //Этот код некорректен, при сохранении статуса тулбара возникнет ошибка
        CMToolBarMenuButton menuButton( UINT(-1),
                popupMenu->GetSafeHmenu(), -1, text);
 
        menuButton.m_bText = TRUE;
        menuButton.m_bImage = FALSE;
        ReplaceButton(m_MenuButtonID, menuButton);
    }
в функции ниже

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void CMComboBoxToolbar::OnReset()
{
    CMFCToolBarComboBoxButton comboBox(m_ComboBoxID, -1, CBS_DROPDOWNLIST, 200);
    ReplaceButton(m_ComboBoxID, comboBox);
 
    //CMFCToolBarButton* b = GetButton(1);
    m_ComboBox = DYNAMIC_DOWNCAST(CMFCToolBarComboBoxButton, GetButton(1));
    ASSERT(m_ComboBox != 0);
    
    LoadButtonMenu();
}
 
void CMComboBoxToolbar::LoadButtonMenu(bool reload)
{
    CString text;
    CMenu menu;
    CMenu* popupMenu;
    menu.LoadMenu(m_PopupMenuID);
    popupMenu = menu.GetSubMenu(0);
    menu.GetMenuString(0, text, MF_BYPOSITION);
    //CMToolBarMenuButton menuButton(m_MenuButtonID, popupMenu->GetSafeHmenu(), -1, text);
    if(!reload)
    {
        //Этот код некорректен, при сохранении статуса тулбара возникнет ошибка
        CMToolBarMenuButton menuButton( UINT(-1),
                popupMenu->GetSafeHmenu(), -1, text);
 
        menuButton.m_bText = TRUE;
        menuButton.m_bImage = FALSE;
        ReplaceButton(m_MenuButtonID, menuButton);
    }
    else
    {
#if 0
        CMToolBarMenuButton menuButton( UINT(-1),
                popupMenu->GetSafeHmenu(), -1, text);
 
        menuButton.m_bText = TRUE;
        menuButton.m_bImage = FALSE;
        ReplaceButton(UINT(-1), menuButton);
        SetButtonWidth(0);
        CalcFixedLayout(false, true);
        RedrawWindow();
        return;
#else
// Такой вариант с глюками, но работает
        CMToolBarMenuButton *button = (CMToolBarMenuButton*) GetButton(0);
        button->CreateFromMenu(popupMenu->GetSafeHmenu());
        button->m_strText = text;
        SetButtonWidth(0);
        //CalcFixedLayout(false, true);
        //RedrawWindow();
        AdjustLayout();
#endif
    }
}
Да в общем я нашёл способ как загружать статус тулбаров:
В MainFrame.h добавить:
C++
1
 afx_msg void OnClose();
В MainFrame.cpp добавить:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
BEGIN_MESSAGE_MAP(CMainFrame, CMMainFrameBase)
    //{{AFX_MSG_MAP(CMainFrame)
    ON_WM_CREATE()
    //ON_WM_TIMER()
    ON_WM_DEVICECHANGE()
        ON_WM_CLOSE()
        ...
 
END_MESSAGE_MAP()
 
 
void CMainFrame::OnClose()
{
        m_ToolBar.SaveState(_T("SOFTWARE\\Test1\\Test2\\Workspace\\")); 
    m_MeasurementToolBar.SaveState(_T("SOFTWARE\\Test1\\Test2\\Workspace\\"));
    m_PeaksToolBar.SaveState(_T("SOFTWARE\\Test1\\Test2\\Workspace\\"));
    m_MenuToolBar.SaveState(_T("SOFTWARE\\Test1\\Test2\\Workspace\\"));
    
    CMDIFrameWndEx::OnClose();
}
 
// Создание главного окна
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// После создания тулбара добавляем код загрузки из реестра, например
 
m_ToolBar.LoadState(_T("SOFTWARE\\Test1\\Test2\\Workspace\\"));
}
Правда работает не очень - на одной линии положение не сохраняется,
да и вообще это скорее костыль и надо переписывать код который участвует при создании и загрузке тулбаров
0
фрилансер
 Аватар для Алексей1153
6466 / 5688 / 1131
Регистрация: 11.10.2019
Сообщений: 15,138
24.07.2022, 01:21
Цитата Сообщение от MaximSergeevith Посмотреть сообщение
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
    // базовый класс не работает
if (!CMDIFrameWndEx::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
    {
        return FALSE;
    }

а где return ?
}
нет return - неопределённое поведение

Добавлено через 2 минуты
проще вот так
C++
1
2
3
4
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
    return CMDIFrameWndEx::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext);
}
Добавлено через 1 минуту
а ещё проще вообще удалить эту функцию, поскольку она просто перевызывает функцию предка
0
5 / 5 / 2
Регистрация: 03.05.2016
Сообщений: 221
24.07.2022, 02:38  [ТС]
Да есть там return - просто я код сократил.
После вызова функции предка будет ошибка дальше.
Как уже писал надо разбираться с этими кастомными функциями

Добавлено через 26 минут
Сейчас у меня такая проблема - тулбары после восстановления сессии не устанавливаются на одной линии.
Т.е. перед закрытием приложения я поставил их в одну линии, открываю приложение
- по вертикали они стоят как было перед закрытием,
по горизонтали - на разных линиях (друг под другом). Как с этим быть?
0
5 / 5 / 2
Регистрация: 03.05.2016
Сообщений: 221
24.07.2022, 11:08  [ТС]
Вернее не так - положение по оси Х у них такое как перед закрытием, а по оси У они размещаются на разных уровнях (полках)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.07.2022, 11:08
Помогаю со студенческими работами здесь

Восстановление предыдущей сессии в Firefox
При закрытии и последующем открытии лисы, восстанавливаются не те вкладки, которые были при закрытии, точнее частично не те. Появляются 3-4...

Уничтожение предыдущей сессии WCF
Здравствуйте, у меня вопрос такой вопрос не могли бы вы подсказать как уничтожать сессию если при аутентификация логин и пароль не подошёл,...

доступ к значениям предыдущей сессии в DLL
Zdravstvuyte! Pomogite pojaluysta reshit problemu. Est DLL, k ney v cikle obrashaetsa programma. Kajdiy noviy shag cikla zagrujaet i...

Вычисление идет с данными из предыдущей сессии
Заполняю данные в формы, нажимаю кнопку вычислить, показывается результат - все ок. Обновляю страницу - формы пустые. Но если нажать...

Восстановление предыдущей сессии в Mozilla Firefox
Ребята, помогите, пожалуйста. Возникла проблема. Были открыты 3 окна firefox с очень большим количеством нужных открытых вкладок. Потом...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru