Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 24.11.08 09:46
Оценка:
Здравствуйте.

Может кому известно, что конкретно нужно подкрутить, чтоб работало нормально.

MFC VSC++ 6.0
Создаю CTreeView in page of CSplitterWnd.
Добавляю необходимые стили в OnCreate & OnInitialUpdate

int CMyTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
lpCreateStruct->style |= TVS_HASLINES | TVS_HASBUTTONS;
lpCreateStruct->style &= ~TVS_NOSCROLL; // где-то на форумах прочитал, что это поможет.

if (CTreeView::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}

void CMyTreeView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();

// this code works (done 22.04.2003), other in CFormView does not work
long style = ::GetWindowLong(m_treeC, GWL_STYLE );
style |= TVS_HASLINES | TVS_HASBUTTONS;
style &= ~TVS_NOSCROLL;
::SetWindowLong(m_treeC, GWL_STYLE, style);

m_icons.Create(IDB_TVICONS, 16, 1, RGB(255, 255, 255));
m_treeC.SetImageList(&m_icons, TVSIL_NORMAL);
}

Заполняю дерево по сообщению после активизации окна (пробовал заполнять и в OnInitialUpdate).

Происходит следующее: Появляется заполненное дерево, а после expand/collapse/selection нет перерисовки.
Принуждаю перерисовку вызовом Invalidate() в соответсвующей обработке методе, но скролбар все-равно не появляется.

После приема/обработки сообщения о перезаполнении дерева работа дерева востанавливается. Перерисовка работает, скролбар появляется/исчезает при открытии/закрытии большого дерева.

Вызов Invalidate() помогает, но все еще нет сколбара .
Подскажите, кто знает причину.
Спасибо.
Re: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 24.11.08 18:03
Оценка:
А с чего бы проявляться вертикальному скролбару если стиль TVS_NOSCROLL отключает оба скролбара? Чтобы отключить только горизонтальный скролбар, нужен стиль TVS_NOHSCROLL, а TVS_NOSCROLL отключает оба, причем этот стиль полностью перегружает стиль горизонтального скролбара — TVS_NOHSCROLL, о чем недвусмысленно написано в header`е из SDK
#define TVS_NOHSCROLL           0x8000  // TVS_NOSCROLL overrides this
Posted via RSDN NNTP Server 2.1 beta
Aml Pages Home
Re[2]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 25.11.08 09:52
Оценка:
Здравствуйте, Carc, Вы писали:

C>А с чего бы проявляться вертикальному скролбару если стиль TVS_NOSCROLL отключает оба скролбара? Чтобы отключить только горизонтальный скролбар, нужен стиль TVS_NOHSCROLL, а TVS_NOSCROLL отключает оба, причем этот стиль полностью перегружает стиль горизонтального скролбара — TVS_NOHSCROLL, о чем недвусмысленно написано в header`е из SDK

C>
C>#define TVS_NOHSCROLL           0x8000  // TVS_NOSCROLL overrides this
C>


Спасибо за ответ, но Вы невнимательно прочитали мой пост.
Там стоит:

lpCreateStruct->style &= ~TVS_NOSCROLL; // где-то на форумах прочитал, что это поможет.

То есть я насильно пытался СНЯТЬ/УБРАТЬ свойство/стиль TVS_NOSCROLL.
В противном случае скролбар не мог бы сам появиться позже после перезаполнения, так как стояло бы свойство NOSCROLL.

Мне нужны оба скролбара и они (после первого наполнения CTreeView) не появляются, не смотря на все мои ухищрения.
Re[3]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Nikita123 Россия  
Дата: 25.11.08 10:54
Оценка:
Здравствуйте, Hex65, Вы писали:

H>Там стоит:

H>lpCreateStruct->style &= ~TVS_NOSCROLL; // где-то на форумах прочитал, что это поможет.
Врядли поможет. У меня написано так:
BOOL CGraphTreeView::PreCreateWindow(CREATESTRUCT& cs)
{
//*****
cs.style |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS; // установить стиль дерева
//*****
return CTreeView::PreCreateWindow(cs); // вызов системного обработчика
}
И все нормально работает — есть вертикальный и горизонтальный скролл-бары.
Желаю успеха,
Никита.
Re[3]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 25.11.08 11:22
Оценка:
H>Спасибо за ответ, но Вы невнимательно прочитали мой пост.
H>Там стоит:

H>lpCreateStruct->style &= ~TVS_NOSCROLL; // где-то на форумах прочитал, что это поможет.


H>То есть я насильно пытался СНЯТЬ/УБРАТЬ свойство/стиль TVS_NOSCROLL.

H>В противном случае скролбар не мог бы сам появиться позже после перезаполнения, так как стояло бы свойство NOSCROLL.
Да Вы — правы. А тильды он и не заметил... Только по умолчанию все равно TVS_NOSCROLL имхо все равно не используется, так что можно и не убирать.
H>Мне нужны оба скролбара и они (после первого наполнения CTreeView) не появляются, не смотря на все мои ухищрения.
Сдается мне тогда проблема в коде заполнения, можно кусок кода и откуда вызывается?
Aml Pages Home
Re[4]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 25.11.08 14:43
Оценка:
Здравствуйте, Carc, Вы писали:

H>>Спасибо за ответ, но Вы невнимательно прочитали мой пост.

H>>Там стоит:

H>>lpCreateStruct->style &= ~TVS_NOSCROLL; // где-то на форумах прочитал, что это поможет.


H>>То есть я насильно пытался СНЯТЬ/УБРАТЬ свойство/стиль TVS_NOSCROLL.

H>>В противном случае скролбар не мог бы сам появиться позже после перезаполнения, так как стояло бы свойство NOSCROLL.
C>Да Вы — правы. А тильды он и не заметил... Только по умолчанию все равно TVS_NOSCROLL имхо все равно не используется, так что можно и не убирать.

Когда непонятно что влияет приходится "давить на все кнопки" .

H>>Мне нужны оба скролбара и они (после первого наполнения CTreeView) не появляются, не смотря на все мои ухищрения.

C>Сдается мне тогда проблема в коде заполнения, можно кусок кода и откуда вызывается?

Есть особенность — дерево закладывается в основном приложении (ехе), а наполняется в длл.
Попробую вынести наполнение в ехе (вдруг поможет). Спасибо за намек.
Re[5]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 25.11.08 15:17
Оценка:
Здравствуйте, Hex65, Вы писали:

H>Здравствуйте, Carc, Вы писали:


H>>>Спасибо за ответ, но Вы невнимательно прочитали мой пост.

H>>>Там стоит:

H>>>lpCreateStruct->style &= ~TVS_NOSCROLL; // где-то на форумах прочитал, что это поможет.


H>>>То есть я насильно пытался СНЯТЬ/УБРАТЬ свойство/стиль TVS_NOSCROLL.

H>>>В противном случае скролбар не мог бы сам появиться позже после перезаполнения, так как стояло бы свойство NOSCROLL.
C>>Да Вы — правы. А тильды он и не заметил... Только по умолчанию все равно TVS_NOSCROLL имхо все равно не используется, так что можно и не убирать.

H>Когда непонятно что влияет приходится "давить на все кнопки" .

Чтобы когда с 33 тремя открытыми апликухами, слепым методом и скоростью набора от восьми с половиной тысяч ударов в минуту начинаешь нажимать кнопочки на клаве в разы быстрее, чем понимать что происходит... вот именно за этим Microsoft и вводит усиленную поддержку управления голосом — чтобы восклик "Куда нижимать-то бли-и-и-ин, рычагов то понаставили" сразу запускал какой-нить таскбар вроде Alt+Tab и человечек обретал душевное спокойствие
H>>>Мне нужны оба скролбара и они (после первого наполнения CTreeView) не появляются, не смотря на все мои ухищрения.
C>>Сдается мне тогда проблема в коде заполнения, можно кусок кода и откуда вызывается?

H>Есть особенность — дерево закладывается в основном приложении (ехе), а наполняется в длл.

H>Попробую вынести наполнение в ехе (вдруг поможет). Спасибо за намек.
Да не! Не причем это, имхо, ДЛЛ она и в Африке ДЛЛ. ДЛЛ — дура, штык молодец! Тут проблема в коде. Вопрос что это за "активация окна" в котором происходит заполнение дерева? Сдается мне в ней и вся проблема, может быть из-за этого перерисовка немного запаздывает. В общем, на код надо взглянуть. Да и по уму лучше все это делать конечно OnInitialUpdate — если в ней что-то не получается, то полагаю это какой-то косяк в коде. Все должно нормально заполняться.
Aml Pages Home
Re[6]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 25.11.08 16:21
Оценка:
Здравствуйте, Carc, Вы писали:

C>Да не! Не причем это, имхо, ДЛЛ она и в Африке ДЛЛ. ДЛЛ — дура, штык молодец! Тут проблема в коде. Вопрос что это за "активация окна" в котором происходит заполнение дерева? Сдается мне в ней и вся проблема, может быть из-за этого перерисовка немного запаздывает. В общем, на код надо взглянуть. Да и по уму лучше все это делать конечно OnInitialUpdate — если в ней что-то не получается, то полагаю это какой-то косяк в коде. Все должно нормально заполняться.


Увидел, что при заполнении использовал TVE_EXPAND вместо TVIS_EXPANDED при проверке статуса, но исправление не помогло.
Симптомы — нет перерисовки до тех пор пока CTreeCtrl не перезаполняется из контейнера.

Логика дерева: сначала заполняется из контекста, по сообщению сохраняется все в контейнере, востанавливается из контейрера если обратились повторно.
// первое наполнение из контеста:
int FillSubTreeCtrl(HTREEITEM parent, ContainerType::ObjType* pObj)
{
    ContainerType::HierarhyIterator it_b, it_e;
    ...
    for ( ; it_b != it_e; it_b++)
    {
        ContainerType::ObjType* pObj = it_b->second;
        LONG objId = pObj->GetId();

        HTREEITEM hItem;        
        if (CanBeShown(context, objId))
        {
            hItem = tree.InsertItem(pObj->GetName(), parent, TVI_SORT);
            tree.SetItemData(hItem, objId);
        }
        else
            hItem = parent;
        FillSubTreeCtrl(hItem, pObj);

        SetItemImage(context, hItem);
    }
}

// функтор проверки исходного начального состояния (expanded) 
void SetExpanded(HTREEITEM hItem)
{
    if ((TVIS_EXPANDED & m_rTreeC.GetItemState(hItem, TVIS_EXPANDED)) == 0)
    {
        //m_rTreeC.SetItemState(hItem, TVIS_EXPANDED, TVIS_EXPANDED);
        m_rTreeC.Expand(hItem, TVE_EXPAND);
        SetImageOpened(m_rTreeC, hItem);    

        hItem = m_rTreeC.GetParentItem(hItem);
        if (hItem)
            SetExpanded(hItem);
    }
}

// функтор востановления из контейнера: после выполнеия этого кода CTreeCtrl работает правильно.
#define ITEM_STATES        (TVIS_SELECTED | TVIS_EXPANDED | TVIS_BOLD)
bool operator () (CTreeCtrl& rTree, HTREEITEM hItem)
{
    if (MTV_STreeData::SItemData* pItem = m_storage.GetItemData())
    {
        rTree.SetItemData(hItem, pItem->itemId);
        rTree.SetItemState(hItem, pItem->state, ITEM_STATES);
        rTree.SetItemImage(hItem, pItem->nImage, pItem->nImage);
        rTree.SetItemText(hItem, pItem->name);

        if (pItem->next & NEXT_ITEM_EXIST)
            rTree.InsertItem(_T(""), rTree.GetParentItem(hItem));
        if (pItem->next & CHILD_ITEM_EXIST)
            rTree.InsertItem(_T(""), hItem);

        // do not return true at all for such work !!!
        return false;
    }
    return true;
}
Re[7]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 25.11.08 16:30
Оценка:
Откуда вызывается FillSubTreeCtrl в TreeView?
Aml Pages Home
Re[8]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 25.11.08 16:40
Оценка:
Здравствуйте, Carc, Вы писали:

C>Откуда вызывается FillSubTreeCtrl в TreeView?


из CMyTreeView::FillTreeCtrl()

CMyTreeView::FillTreeCtrl() в CMyTreeView::OnSelectCommand()


LONG CMyTreeView::OnSelectCommand(UINT wParam, LONG lParam)
{
    switch (wParam)     {
    case idCArea:
        if (m_areaId != lParam)
        {
            CTreeCtrlMap* pTreeData = CheckTreeDataMap();
            if (m_areaId >= 0)
                pTreeData->SaveData(m_areaId, m_treeC);
            
            m_areaId = lParam;

            m_treeC.DeleteAllItems();
            if (pTreeData->RestoreData(m_areaId, m_treeC) == false)
                FillTreeCtrl(m_areaId);
        }
        break;
    }


Попробую постмессагой выполнить это позже.
Re[9]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 25.11.08 18:22
Оценка:
H>Попробую постмессагой выполнить это позже.
Меня интересовало в обработчике какого сообщения это все иницируется — весь стек вызовов приводящий к FillTreeCtrl()?
Aml Pages Home
Re[10]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 26.11.08 09:06
Оценка:
Здравствуйте, Carc, Вы писали:

H>>Попробую постмессагой выполнить это позже.

C>Меня интересовало в обработчике какого сообщения это все иницируется — весь стек вызовов приводящий к FillTreeCtrl()?

Cтэк первого вызова FillTree

CMatrixTreeView::FillTree(long 1) line 679
CMatrixTreeView::OnSelectCommand(unsigned int 1, long 1) line 494 + 23 bytes
CWnd::OnWndMsg(unsigned int 1228, unsigned int 1, long 1, long * 0x0012e5b0) line 1815 + 17 bytes
CWnd::WindowProc(unsigned int 1228, unsigned int 1, long 1) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x059c08f8 {CMatrixTreeView hWnd=0x00040318}, HWND__ * 0x00040318, unsigned int 1228, unsigned int 1, long 1) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00040318, unsigned int 1228, unsigned int 1, long 1) line 368
AfxWndProcBase(HWND__ * 0x00040318, unsigned int 1228, unsigned int 1, long 1) line 220 + 21 bytes
USER32! 77d18709()
USER32! 77d187eb()
USER32! 77d189a5()
USER32! 77d189e8()
USER32! 77d3ea3b()
USER32! 77d2688a()
USER32! 77d3b7c5()
USER32! 77d3b12b()
USER32! 77d65fdf()
USER32! 77d50574()
USER32! 77d6615b()
CWinApp::DoMessageBox(const unsigned short * 0x00b22d00, unsigned int 48, unsigned int 0) line 113 + 25 bytes
AfxMessageBox(const unsigned short * 0x00b22d00, unsigned int 0, unsigned int 0) line 131 + 26 bytes
CBaseAdmDoc::OnDBConnect() line 1598
CBaseAdmView::OnConnectDb() line 141
_AfxDispatchCmdMsg(CCmdTarget * 0x02d92c70 {CBaseAdmView}, unsigned int 1101, int 0, void (void)* 0x005ede50 CBaseAdmView::OnConnectDb(void), void * 0x00000000, unsigned int 12, AFX_CMDHANDLERINFO * 0x00000000) line 88
CCmdTarget::OnCmdMsg(unsigned int 1101, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes
CView::OnCmdMsg(unsigned int 1101, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 162 + 24 bytes
CWnd::OnCommand(unsigned int 1101, long 131806) line 2088
CWnd::OnWndMsg(unsigned int 273, unsigned int 1101, long 131806, long * 0x0012f798) line 1597 + 28 bytes
CWnd::WindowProc(unsigned int 273, unsigned int 1101, long 131806) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x02d92c70 {CBaseAdmView hWnd=???}, HWND__ * 0x000202ea, unsigned int 273, unsigned int 1101, long 131806) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x000202ea, unsigned int 273, unsigned int 1101, long 131806) line 368
AfxWndProcBase(HWND__ * 0x000202ea, unsigned int 273, unsigned int 1101, long 131806) line 220 + 21 bytes
USER32! 77d18709()
USER32! 77d187eb()
USER32! 77d1b368()
USER32! 77d1b3b4()
NTDLL! 7c91eae3()
USER32! 77d1b7ab()
USER32! 77d4fc9d()
USER32! 77d46530()
USER32! 77d28386()
USER32! 77d2758c()
USER32! 77d18709()
USER32! 77d187eb()
USER32! 77d1c00e()
USER32! 77d1c034()
CWnd::DefWindowProcW(unsigned int 514, unsigned int 0, long 852016) line 1000 + 32 bytes
CWnd::WindowProc(unsigned int 514, unsigned int 0, long 852016) line 1586 + 26 bytes
AfxCallWndProc(CWnd * 0x02d92d7c {CButton hWnd=0x000202de}, HWND__ * 0x000202de, unsigned int 514, unsigned int 0, long 852016) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x000202de, unsigned int 514, unsigned int 0, long 852016) line 368
AfxWndProcBase(HWND__ * 0x000202de, unsigned int 514, unsigned int 0, long 852016) line 220 + 21 bytes
USER32! 77d18709()
USER32! 77d187eb()
USER32! 77d189a5()
USER32! 77d189e8()
USER32! 77d3e819()
CWnd::IsDialogMessageW(tagMSG * 0x00ba3e20 {msg=0x00000202 wp=0x00000000 lp=0x000a001f}) line 182
CWnd::PreTranslateInput(tagMSG * 0x00ba3e20 {msg=0x00000202 wp=0x00000000 lp=0x000a001f}) line 3424
CFormView::PreTranslateMessage(tagMSG * 0x00ba3e20 {msg=0x00000202 wp=0x00000000 lp=0x000a001f}) line 213
CWnd::WalkPreTranslateTree(HWND__ * 0x001603d8, tagMSG * 0x00ba3e20 {msg=0x00000202 wp=0x00000000 lp=0x000a001f}) line 2667 + 18 bytes
CWinThread::PreTranslateMessage(tagMSG * 0x00ba3e20 {msg=0x00000202 wp=0x00000000 lp=0x000a001f}) line 672 + 18 bytes
CLdbAdmApp::PreTranslateMessage(tagMSG * 0x00ba3e20 {msg=0x00000202 wp=0x00000000 lp=0x000a001f}) line 958
CWinThread::PumpMessage() line 848 + 30 bytes
CWinThread::Run() line 487 + 11 bytes
CWinApp::Run() line 400
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, unsigned short * 0x0002068a, int 1) line 49 + 11 bytes
wWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, unsigned short * 0x0002068a, int 1) line 30
wWinMainCRTStartup() line 330 + 55 bytes
KERNEL32! 7c81
Re[11]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 26.11.08 13:18
Оценка:
Ох...
CMatrixTreeView::OnSelectCommand...
какое-то оконное сообщение обрабатывает? Что это за мистическая "активация окна"?
Aml Pages Home
Re[12]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 26.11.08 15:05
Оценка:
Здравствуйте, Carc, Вы писали:

C>Ох...

C>CMatrixTreeView::OnSelectCommand...
C>какое-то оконное сообщение обрабатывает? Что это за мистическая "активация окна"?

это прилетает постмессадж посланный из MainFrame перед самым выходом из OnTreeMatrix() — создание CView — моего CSpltterWnd с вложенным CTreeView.

ON_COMMAND(ID_MATRIX, OnTreeMatrix);

Попробую избавиться от этого .
Re[13]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 26.11.08 16:09
Оценка:
Здравствуйте, Hex65, Вы писали:

H>Здравствуйте, Carc, Вы писали:


C>>Ох...

C>>CMatrixTreeView::OnSelectCommand...
C>>какое-то оконное сообщение обрабатывает? Что это за мистическая "активация окна"?

H>это прилетает постмессадж посланный из MainFrame перед самым выходом из OnTreeMatrix() — создание CView — моего CSpltterWnd с вложенным CTreeView.


H>ON_COMMAND(ID_MATRIX, OnTreeMatrix);


H>Попробую избавиться от этого .

Та не! Ни то!
Я как бы типа догадывался что всё это WM_COMMAND сообщение — но оно откуда то берется? Меню, кнопка, сами шлете? Откуда!
Хочеться понять, что если есть PostMessage, то как то он образуется. Вопрос когда? На каком действии пользователя? Ну я не знаю, к примеру, потеря фокуса CView, какой-нить WM_MOUSEMOVE — т.е. по большому счету должно быть некоторое событие от пользователя (пошел в другой вид), и отсюда вся цепочка (тоже к примеру) WM_KILLFOCUS а там PostMessage(WM_COMMAND) и.т.д.
Полагаю что проблема именно в этом самом событии изначальном. Ну или вариант руками отрисоваться (SetWindowPos+SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED) или те же RedrawWindow.
Или надо смотреть в код, какая то странная проблема — дерево "дергается" явно не в тот момент, когда должно "дергаться" настоящее (true) по попу дерявянное и неслабо написанное дерево. Из постов выше скадывается ощущение какой-то архитектурной "неловкости" — что-то вдруг всё выкладывается, то вдруг обратно закладывается... Ну да про архитектуру "горе-советников" много, поэтому и не стоит заморачиваться. Но ощущение, что проявляется она именно в том, что не нужный момент дерево сворачивается\разворачиватся...
Вот собственно начальный момент какой? PostMessage это всё следствия — это нюансы, не в них дело!
Aml Pages Home
Re[14]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 27.11.08 09:48
Оценка:
Здравствуйте, Carc, Вы писали:

C>Здравствуйте, Hex65, Вы писали:


H>>Здравствуйте, Carc, Вы писали:


C>>>Ох...

C>>>CMatrixTreeView::OnSelectCommand...
C>>>какое-то оконное сообщение обрабатывает? Что это за мистическая "активация окна"?

H>>это прилетает постмессадж посланный из MainFrame перед самым выходом из OnTreeMatrix() — создание CView — моего CSpltterWnd с вложенным CTreeView.


H>>ON_COMMAND(ID_MATRIX, OnTreeMatrix);


H>>Попробую избавиться от этого .

C>Та не! Ни то!
C>Я как бы типа догадывался что всё это WM_COMMAND сообщение — но оно откуда то берется? Меню, кнопка, сами шлете? Откуда!
C>Хочеться понять, что если есть PostMessage, то как то он образуется. Вопрос когда? На каком действии пользователя? Ну я не знаю, к примеру, потеря фокуса CView, какой-нить WM_MOUSEMOVE — т.е. по большому счету должно быть некоторое событие от пользователя (пошел в другой вид), и отсюда вся цепочка (тоже к примеру) WM_KILLFOCUS а там PostMessage(WM_COMMAND) и.т.д.
C>Полагаю что проблема именно в этом самом событии изначальном. Ну или вариант руками отрисоваться (SetWindowPos+SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED) или те же RedrawWindow.
C>Или надо смотреть в код, какая то странная проблема — дерево "дергается" явно не в тот момент, когда должно "дергаться" настоящее (true) по попу дерявянное и неслабо написанное дерево. Из постов выше скадывается ощущение какой-то архитектурной "неловкости" — что-то вдруг всё выкладывается, то вдруг обратно закладывается... Ну да про архитектуру "горе-советников" много, поэтому и не стоит заморачиваться. Но ощущение, что проявляется она именно в том, что не нужный момент дерево сворачивается\разворачиватся...
C>Вот собственно начальный момент какой? PostMessage это всё следствия — это нюансы, не в них дело!

Спасибо за участие в разборе проблемы.
Во-первых, мне самому не нравится эта реализация, но остановился на ней т.к. более правильную(?) решить не удалось.
ОК. Отступление: Сначала о исходной задаче. Ранее уже обсуждалось здесь.

Мне нужно иметь переключаемые деревья, по комбобоксу из одного окна переключаться между деревьями. Удалять деревья нежелательно, т.к важны статусы элементов. Попытка реализовать несколько CTreeCtrl в одном CTreeView не удалась. Потому решил при переключении сохранять/восстанавливать.

Если попробовать еще раз, то сейчас пришла след мысль на реализацию: при переключении CTreeCtrl Detach/Attach либо Create & Fill.
Плохо, что в системе будет фактически несколько ресурсов-CTreeCtrl, а один — только их wrapper класс.

Во-вторых, дерево наполняется и/или восстанавливается в одной функции, на одном сообщении, и после восстановления функционирует номально, а после чзаполнения — нет. Наполнять приходится, когда переключаемся к дереву, которое еще не загружали. Эта основная непонятка, Чем наполнение отличается от восстановления. (посмотрю еще когда именно восстанавливается работоспособность дерева).

Могу первое наполнение сделать в OnInitialUpdate(), но переключение между деревьями в последующем через сообщение необходимо.
Уже писал, что фактически нет перерисовки вообще, включая сколбар, но обработка реакции есть. И вставив везде Invalidate() отрисовка есть, а скролбара все-равно нет.

Попробую вникнуть в Ваше предложение.
Не понимаю, как определить начальный момент и что Вы под ним понимаете.

OnTreeMatrix — функция обработки МЕНЮ, далее ее код:

void CMainFrame::OnTreeMatrix() 
{
    if (0 == m_pMatrixTreeDblViewTemplate)
    {
        m_pMatrixTreeDblViewTemplate = new CMultiDocTemplate(
            IDR_BASEADMTYPE,
            RUNTIME_CLASS(CLdbAdmDoc),    // document class
            RUNTIME_CLASS(CMyChildFrame),   // child frame - реализован на CSplitterWnd
            RUNTIME_CLASS(CMatrixView));    // one from 3 CView: CSelectView, CTreeView, CMatrixView 
    }
    CBaseAdmDoc *doc = GetBaseDocument();

    CMatrixView *mView = doc->GetMatrixView();
    if (mView)
    {
        // allready opened => activate & return
        return;
    }

    CMDIChildWnd* pActiveChild = MDIGetActive();
    CMatrix *matrix = doc->CreateMatrix(typeMView);

    CFrameWnd* pFrame = m_pMatrixTreeDblViewTemplate->
                CreateNewFrame(pDocument, pActiveChild);

    CMatrixSelectView *aView = ...;
    CMatrixTreeView* tree1 = ...;
    CMatrixTreeView* tree2 = ...;

    // call OnInitinalUpdate() of views
    m_pMatrixTreeDblViewTemplate->InitialUpdateFrame(pFrame, doc);
    pFrame->SetActiveView(mView);

    LONG selectedId = matrix->GetId();
    aView->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
    tree1->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
    tree2->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
}


Буду рад услышать Ваши идеи, где я туплю .
Re[15]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 27.11.08 13:13
Оценка:
В-о-о-о! Отлично, уже как-то понятнее!
void CMainFrame::OnTreeMatrix() 
{
       // А НАФИГА ТУТ PostMessage?
       // по моему вполне сойдет и SendMessage - PostMessage асинхронная, а зачем нам тут асинхронность? Создали
       // дерево, и понеслась заполнять. Так?
    aView->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
    tree1->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
    tree2->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
}

2) Ну и судя по коду создания, привязка там плотная, т.е. создаются и конкретные виды и иже с ними. Тогда почему бы напрямую безо всяких Send(Post)Message не начать заполнять дерево сразу из функции OnTreeMatrix? А заполнив его уже и показывать документ (InitialUpdateFrame+SetActiveView), так например!?! Сдается мне это выход... Создание видов, документов — породит массу событий, а тут какие-то PostMessage — а когда они всплывует в tree1, tree2 еще бабка надвое сказала...
Aml Pages Home
Re[16]: Отсутствие перерисовки в CTreeView. MFC bug?
От: Hex65  
Дата: 27.11.08 16:15
Оценка:
Здравствуйте, Carc, Вы писали:

C>В-о-о-о! Отлично, уже как-то понятнее!

C>
C>void CMainFrame::OnTreeMatrix() 
C>{
C>       // А НАФИГА ТУТ PostMessage?
C>       // по моему вполне сойдет и SendMessage - PostMessage асинхронная, а зачем нам тут асинхронность? Создали
C>       // дерево, и понеслась заполнять. Так?
C>    aView->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
C>    tree1->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
C>    tree2->PostMessage(WM_MATRIXVIEW_SELECT_MSG, 0, selectedId);
C>}
C>


Поставил SendMessage() , по-прежнему не работает.

C>2) Ну и судя по коду создания, привязка там плотная, т.е. создаются и конкретные виды и иже с ними. Тогда почему бы напрямую безо всяких Send(Post)Message не начать заполнять дерево сразу из функции OnTreeMatrix? А заполнив его уже и показывать документ (InitialUpdateFrame+SetActiveView), так например!?! Сдается мне это выход... Создание видов, документов — породит массу событий, а тут какие-то PostMessage — а когда они всплывует в tree1, tree2 еще бабка надвое сказала...


Вернусь к этой проблеме позже, сейчас занят другим .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.