Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 25.04.05 10:12
Оценка:
Доброе время суток всем.
Суть дела вот в чем: есть CMainFrame, в нем CSplitterWindow, в нем CDialogImpl, у этого диалога есть CTabCtrl с 3 вкладками (в которых я помещаю, в зависимости от выбранной вкладки, динамически созданные диалоги CDialogImpl). Так вот на одной вкладке (там два баттона и два статика) я сам рисую прямоугольники с помощью SetPixel(...). Проблема в том, что когда сварачиваешь окно, а потом разворачиваешь, нарисованные мною прямоугольники исчезают, в чем трабла??? У этого диалога я определил OnPaint:

LRESULT CColourSet::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    CBrush br;
    RECT rcRect;
    CDC m_DC;

    LRESULT res = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);

    drawColRect();  // моя функция отрисовки прямоугольника
    
    m_ClrLine.GetClientRect(&rcRect);
    m_DC.m_hDC = m_ClrLine.GetDC();
    br.CreateSolidBrush(line);
    m_DC.FillRect(&rcRect, br.m_hBrush);
    m_ClrLine.ReleaseDC(m_DC.m_hDC);
    m_DC.m_hDC = NULL;
    
    br.DeleteObject();

    m_ClrPit.GetClientRect(&rcRect);
    m_DC.m_hDC = m_ClrPit.GetDC();
    br.CreateSolidBrush(pit);
    m_DC.FillRect(&rcRect, br.m_hBrush);
    m_ClrPit.ReleaseDC(m_DC.m_hDC);
    m_DC.m_hDC = NULL;
    
    return 1;
}

...

LRESULT CColourSet::OnErase(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    return 1;
}


Скажи пожалуйста хоть где искать ошибку.
Per aspera ad astra
Re: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 25.04.05 12:21
Оценка:
Здравствуйте, Darked, Вы писали:

Во-первых, в обработчике OnPaint нужно использовать BeginPaint, а не GetDC
Во-вторых, нельзя вызывать ::DefWindowProc, нужно вызывать член класса DefWindowProc, можешь даже без параметра
Но в обработчике WM_PAINT вообще лучше не вызывать эту функцию (хотя может понадобится для диалогов, но в таком случае ::DefWindowProc тебе точно не подойдет, так как в диалоге другая дефолтная функция)
В-третьих, что за стиль программирования объявлять локальную переменную с префиксом m_
В-четвертых, где код drawColRect()

D>[ccode]

D>LRESULT CColourSet::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
D>{
D> CBrush br;
D> RECT rcRect;
D> CDC m_DC;

D> LRESULT res = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);


D> drawColRect(); // моя функция отрисовки прямоугольника


D> m_ClrLine.GetClientRect(&rcRect);

D> m_DC.m_hDC = m_ClrLine.GetDC();
D> br.CreateSolidBrush(line);
D> m_DC.FillRect(&rcRect, br.m_hBrush);
D> m_ClrLine.ReleaseDC(m_DC.m_hDC);
D> m_DC.m_hDC = NULL;

D> br.DeleteObject();


D> m_ClrPit.GetClientRect(&rcRect);

D> m_DC.m_hDC = m_ClrPit.GetDC();
D> br.CreateSolidBrush(pit);
D> m_DC.FillRect(&rcRect, br.m_hBrush);
D> m_ClrPit.ReleaseDC(m_DC.m_hDC);
D> m_DC.m_hDC = NULL;

D> return 1;

D>}
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[2]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 25.04.05 17:55
Оценка:
Здравствуйте, SaloS, Вы писали:

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


SS>Во-первых, в обработчике OnPaint нужно использовать BeginPaint, а не GetDC

Почему же именно только BeginPaint, что — то не видел я в WTL-их исходниках вообще BeginPaint, если честно.

SS>Во-вторых, нельзя вызывать ::DefWindowProc, нужно вызывать член класса DefWindowProc, можешь даже без параметра

Посмтрел я член класса DefWindowProc, это же вроде вообще пустышка, которая только возвращает False.

SS>Но в обработчике WM_PAINT вообще лучше не вызывать эту функцию (хотя может понадобится для диалогов, но в таком случае ::DefWindowProc тебе точно не подойдет, так как в диалоге другая дефолтная функция)

SS>В-третьих, что за стиль программирования объявлять локальную переменную с префиксом m_
А в чем проблема?

SS>В-четвертых, где код drawColRect()

Вот код:

void CColourSet::drawColRect()
{
    RECT rcClient;
    int xBegin, yBegin;
    int colRGB;
    CDC m_CDC;
    
    // вывод прямоугольника для выбора цвета
/*******************************************************************/
    GetClientRect(&rcClient);

    xBegin = rcClient.left + 70;
    yBegin = rcClient.top + 50; 

    m_CDC.m_hDC = GetDC();

    ATLASSERT(m_CDC.m_hDC);
    if(m_CDC.m_hDC)
    {
        for(int i = 0; i < 140; i++)
        {
            for(int j = 0; j < 100; j++)
            {
                colRGB = colors(i, j, 140, 100); // функция возвращает значение цвета RGB
                m_CDC.SetPixel(xBegin + i, yBegin + j, (COLORREF)colRGB);
            }
        } 
    }

    ReleaseDC(m_CDC.m_hDC);
/********************************************************************/
}
Per aspera ad astra
Re[3]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 26.04.05 06:12
Оценка:
Здравствуйте, Darked, Вы писали:

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


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


SS>>Во-первых, в обработчике OnPaint нужно использовать BeginPaint, а не GetDC

D> Почему же именно только BeginPaint, что — то не видел я в WTL-их исходниках вообще BeginPaint, если честно.
По этому поводу почитай MSDN. Там черным (или серым) по белому написано, что в обработчике WM_PAINT для получения контекста устройства нужно вызывать BeginPaint. То что ты видел ничего не значит, и вместо того чтобы спорить просто проверил бы

SS>>Во-вторых, нельзя вызывать ::DefWindowProc, нужно вызывать член класса DefWindowProc, можешь даже без параметра

D> Посмтрел я член класса DefWindowProc, это же вроде вообще пустышка, которая только возвращает False.
Не совсем пустышка, она вызывает стандартную функцию обработки, а это может быть очень важно для сабклассированных контролов. Для диалога, чтоб ты знал стандартная функция DefDlgProc, а не DefWindowProc.

SS>>Но в обработчике WM_PAINT вообще лучше не вызывать эту функцию (хотя может понадобится для диалогов, но в таком случае ::DefWindowProc тебе точно не подойдет, так как в диалоге другая дефолтная функция)

SS>>В-третьих, что за стиль программирования объявлять локальную переменную с префиксом m_
D> А в чем проблема?
префикс m_ это обозначение переменной класса. Для читабильности кода нужно соблюдать хоть какую натацию (но желательно одну и только одну, а не как у тебя).

SS>>В-четвертых, где код drawColRect()

D> Вот код:

D>
D>void CColourSet::drawColRect()
D>{
D>    RECT rcClient;
D>    int xBegin, yBegin;
D>    int colRGB;
D>    CDC m_CDC;

В данном случае тебе нужно использовать СDCHandle, так как в деструкторе будет попытка удалить DC, который ты не создавал, а получал. Последствия этого я тебе не могу описать.
    
D>    // вывод прямоугольника для выбора цвета
D>/*******************************************************************/
D>    GetClientRect(&rcClient);

D>    xBegin = rcClient.left + 70;
D>    yBegin = rcClient.top + 50; 
D>    m_CDC.m_hDC = GetDC();

Более красиво было бы m_CDC = BeginPaint() или m_CDC.Attach(BeginPaint())

D>    ATLASSERT(m_CDC.m_hDC);
D>    if(m_CDC.m_hDC)
D>    {
D>        for(int i = 0; i < 140; i++)
D>        {
D>            for(int j = 0; j < 100; j++)
D>            {
D>                colRGB = colors(i, j, 140, 100); // функция возвращает значение цвета RGB
D>                m_CDC.SetPixel(xBegin + i, yBegin + j, (COLORREF)colRGB);
D>            }
D>        } 
D>    }

D>    ReleaseDC(m_CDC.m_hDC);
D>/********************************************************************/
D>}
D>
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[4]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 26.04.05 06:58
Оценка:
SS>>>В-четвертых, где код drawColRect()
D>> Вот код:

D>>
D>>void CColourSet::drawColRect()
D>>{
D>>    RECT rcClient;
D>>    int xBegin, yBegin;
D>>    int colRGB;
D>>    CDC m_CDC;
SS>

SS>В данном случае тебе нужно использовать СDCHandle, так как в деструкторе будет попытка удалить DC, который ты не создавал, а получал. Последствия этого я тебе не могу описать.
SS>
    
D>>    // вывод прямоугольника для выбора цвета
D>>/*******************************************************************/
D>>    GetClientRect(&rcClient);

D>>    xBegin = rcClient.left + 70;
D>>    yBegin = rcClient.top + 50; 
D>>    m_CDC.m_hDC = GetDC();
SS>

SS> Более красиво было бы m_CDC = BeginPaint() или m_CDC.Attach(BeginPaint())
SS>

D>>    ATLASSERT(m_CDC.m_hDC);
D>>    if(m_CDC.m_hDC)
D>>    {
D>>        for(int i = 0; i < 140; i++)
D>>        {
D>>            for(int j = 0; j < 100; j++)
D>>            {
D>>                colRGB = colors(i, j, 140, 100); // функция возвращает значение цвета RGB
D>>                m_CDC.SetPixel(xBegin + i, yBegin + j, (COLORREF)colRGB);
D>>            }
D>>        } 
D>>    }
D>>

Если будешь использовать BeginPaint, то нужно для завершения использовать EndPaint
D>>
D>>    ReleaseDC(m_CDC.m_hDC);
D>>/********************************************************************/
D>>}
D>>
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[5]: Проблемы с перерисовкой, хотя OnPaint() есть
От: BuHHunyx Беларусь  
Дата: 26.04.05 07:42
Оценка:
Здравствуйте, SaloS, Вы писали:

SS>Если будешь использовать BeginPaint, то нужно для завершения использовать EndPaint


CPaintDC решит все проблемы
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Re[6]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 26.04.05 10:01
Оценка:
Здравствуйте, BuHHunyx, Вы писали:

Согласен

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


SS>>Если будешь использовать BeginPaint, то нужно для завершения использовать EndPaint


BHH>CPaintDC решит все проблемы
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[4]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 26.04.05 11:34
Оценка:
Переписал я так:

void CColourSet::drawColRect()
{
  RECT rcClient;
  int xBegin, yBegin;
  int colRGB;
  CPaintDC m_DC(m_hWnd);
    
    // вывод прямоугольника для выбора цвета
/*******************************************************************/
    GetClientRect(&rcClient);

    xBegin = rcClient.left + 70;
    yBegin = rcClient.top + 50; 

    if(m_CDC.m_hDC)
    {
        for(int i = 0; i < 140; i++)
        {
            for(int j = 0; j < 100; j++)
            {
                colRGB = colors(i, j, 140, 100);
                m_CDC.SetPixel(xBegin + i, yBegin + j, (COLORREF)colRGB);
            }
        } 
    }
}

И ничего не изменилось.
Per aspera ad astra
Re[5]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 26.04.05 12:44
Оценка:
Здравствуйте, Darked, Вы писали:
А все остальное в OnPaint, также переделал?
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[6]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 27.04.05 05:03
Оценка: -1
Здравствуйте, SaloS, Вы писали:

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

SS>А все остальное в OnPaint, также переделал?

Ну в конечном варианте OnPaint() теперь выглядит так:

LRESULT CColourSet::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    CBrush br;
    RECT rcRect;
    CPaintDC DC(m_hWnd);
    CClientDC clDC(m_hWnd);

    drawColRect(DC.m_hDC);
    
    m_ClrLine.GetClientRect(&rcRect);
    clDC.m_hDC = m_ClrLine.GetDC();
    br.CreateSolidBrush(line);
    clDC.FillRect(&rcRect, br.m_hBrush);
    clDC.Detach();
    
    br.DeleteObject();

    m_ClrPit.GetClientRect(&rcRect);
    clDC.m_hDC = m_ClrPit.GetDC();
    br.CreateSolidBrush(pit);
    clDC.FillRect(&rcRect, br.m_hBrush);

    return 0;
}

DefDlgProc(m_hWnd, uMsg, wParam, lParam) я убрал, поскольку происходит вызов моей OnPaint(), зацикливаается пока не падает с переполнением. DefDlgProc() — нет такой, без параметров, поэтому убрал совсем.

В итоге все по — прежнему. Мне кажется где — то запарка с собощениями, кто — то скорее всего тоже получает WM_PAINT и перерисовывает мое окно после меня.
Per aspera ad astra
Re[7]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 27.04.05 07:23
Оценка:
Здравствуйте, Darked, Вы писали:

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


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

SS>>А все остальное в OnPaint, также переделал?

D> Ну в конечном варианте OnPaint() теперь выглядит так:


D>
D>LRESULT CColourSet::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
D>{
D>    CBrush br;
D>    RECT rcRect;
D>    CPaintDC DC(m_hWnd);
D>    CClientDC clDC(m_hWnd);

Сколько можно говорить, что нельзя использовать GetDC (а конструктор CClientDC вызывает именно его) в обработчике WM_PAINT
D>    drawColRect(DC.m_hDC);
    
D>    m_ClrLine.GetClientRect(&rcRect);
D>    clDC.m_hDC = m_ClrLine.GetDC();
D>    br.CreateSolidBrush(line);
D>    clDC.FillRect(&rcRect, br.m_hBrush);
D>    clDC.Detach();

D>    br.DeleteObject();

D>    m_ClrPit.GetClientRect(&rcRect);
D>    clDC.m_hDC = m_ClrPit.GetDC();
D>    br.CreateSolidBrush(pit);
D>    clDC.FillRect(&rcRect, br.m_hBrush);

D>    return 0;
D>}
D>


D> В итоге все по — прежнему. Мне кажется где — то запарка с собощениями, кто — то скорее всего тоже получает WM_PAINT и перерисовывает мое окно после меня.


Вот данный обработчик работает точно
{
CPaintDC DC(m_hWnd);
DC.Rectangle(20, 20, 50, 50);
return 0;
}
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re: Проблемы с перерисовкой, хотя OnPaint() есть
От: ACR Россия  
Дата: 27.04.05 07:54
Оценка:
ОнПаинт
{
бегин паинт
рисуешь до
енд паинт

дефвиндовпрог()

бегин паинт
рисуешь после
енд паинт
}

не вызывай гетдиси батхед.
Re[8]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 27.04.05 09:21
Оценка:
Так делов том, что даже если я делаю так:

LRESULT CColourSet::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    CBrush br;
    RECT rcRect;
    CPaintDC DC(m_hWnd);
//    CClientDC clDC(m_hWnd);

    drawColRect(DC.m_hDC);
    
/*    m_ClrLine.GetClientRect(&rcRect);
    clDC.m_hDC = m_ClrLine.GetDC();
    br.CreateSolidBrush(line);
    clDC.FillRect(&rcRect, br.m_hBrush);
    clDC.Detach();
    br.DeleteObject();

    m_ClrPit.GetClientRect(&rcRect);
    clDC.m_hDC = m_ClrPit.GetDC();
    br.CreateSolidBrush(pit);
    clDC.FillRect(&rcRect, br.m_hBrush); */

    return 0;
}

То даже это единственный прямоугольник все равно не перерисовывается!!!
Per aspera ad astra
Re[9]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 27.04.05 11:47
Оценка:
Здравствуйте, Darked, Вы писали:

Ты там что-то писал про WM_ERASEBKND, может убери обработчик на эту месагу, и кстати покажи какие сообщения ты обрабатываешь, а еще лучше запости исходники (желательно которые можно скомпилить и запустить)
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[10]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 27.04.05 11:54
Оценка:
Здравствуйте, SaloS, Вы писали:

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


SS>Ты там что-то писал про WM_ERASEBKND, может убери обработчик на эту месагу, и кстати покажи какие сообщения ты обрабатываешь, а еще лучше запости исходники (желательно которые можно скомпилить и запустить)


Не, WM_ERASEBKND — просто убирает флики. исходникне могу запостить, я использую несколько чужих dll, без которых не запустится, да и я использую несколько изображений в особом формате, которые тоже выслать не могу, секретность
Я проверил, такая фигня происходит на любой вкладке от CTabCtrl. Если я рисую на CDialogImpl, на котором находится CTabCtrl, то все ок. Где — то тут с сообщениями лажа, или хз.
Per aspera ad astra
Re[11]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 27.04.05 12:26
Оценка:
D> Не, WM_ERASEBKND — просто убирает флики.
Вообще WM_ERASEBKND не убирает флики, оно рисует фон. То есть, если ты хочешь чтобы окно стало прозрачным, просто при обработке этого сообщения ничего не делай, вот и все. А для уборки фликов делают немного по-другому. Всю перерисовку окна заключают в обработчик WM_ERASEBKND, причем сначала рисуют в памяти, а потом блитят в HDC который тебе приходит. вот.

D> Я проверил, такая фигня происходит на любой вкладке от CTabCtrl. Если я рисую на CDialogImpl, на котором находится CTabCtrl, то все ок. Где — то тут с сообщениями лажа, или хз.

А парентом для вкладки является CTabCtrl? Если да, то проверь, чтобы у таб контрола не менялись размеры, и при минимайзе область, где ты рисуешь не была невидимой. Потому, что если ты рисуешь на невидимой области, то то что ты нарисуешь тоже будет невидимым
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[12]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 27.04.05 18:12
Оценка:
Здравствуйте, SaloS, Вы писали:


D>> Не, WM_ERASEBKND — просто убирает флики.

SS>Вообще WM_ERASEBKND не убирает флики, оно рисует фон. То есть, если ты хочешь чтобы окно стало прозрачным, просто при обработке этого сообщения ничего не делай, вот и все. А для уборки фликов делают немного по-другому. Всю перерисовку окна заключают в обработчик WM_ERASEBKND, причем сначала рисуют в памяти, а потом блитят в HDC который тебе приходит. вот.

D>> Я проверил, такая фигня происходит на любой вкладке от CTabCtrl. Если я рисую на CDialogImpl, на котором находится CTabCtrl, то все ок. Где — то тут с сообщениями лажа, или хз.

SS>А парентом для вкладки является CTabCtrl? Если да, то проверь, чтобы у таб контрола не менялись размеры, и при минимайзе область, где ты рисуешь не была невидимой. Потому, что если ты рисуешь на невидимой области, то то что ты нарисуешь тоже будет невидимым

В обработчике WM_ERASEBKND у меня стоит только return 1, что убрало перерисовку фона, а соотвественно и флики (по — крайней мере в данном случае).
Да, вкладки у меня на CTabCTrl. Чего — то я не понял про минимайз, объясни пжалуста по-подробнее.


// функция создания вклодок
bool Cw32View::createTabs(void)
{
    CString str;    
    RECT rec;

    CWindow tab = CWindow(GetDlgItem(IDC_TAB_TYPE));
//    tab.ModifyStyle(0,WS_EX_CONTROLPARENT);

    tab.GetClientRect(&rec);

    m_TabType.Create(tab.m_hWnd, &rec , NULL, TCS_TABS |TCS_RAGGEDRIGHT | WS_CHILD | WS_VISIBLE , 0, 0U, NULL);
    
    TC_ITEM TabCtrlItem = {0};
    TabCtrlItem.mask = TCIF_TEXT;
    _ASSERT(str.LoadString(IDS_STRING10271)) ;
    TabCtrlItem.cchTextMax = str.GetLength();
    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

    TabCtrlItem.iImage = -1;                
    m_TabType.InsertItem( 0, &TabCtrlItem );

    _ASSERT(str.LoadString(IDS_STRING10272)) ;
    TabCtrlItem.cchTextMax = str.GetLength();
    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

    TabCtrlItem.iImage = -1;                
    m_TabType.InsertItem( 1, &TabCtrlItem );

    m_TabType.SetCurSel(0);
    m_TabType.ShowWindow (SW_SHOW);

    
    RECT rc ;
    m_TabType.GetWindowRect(&rc) ; 
    m_TabType.AdjustRect(FALSE, &rc);
    ScreenToClient(&rc) ;
    
    //создаем объект интегрального диалога
    m_Integral = new CIntegral(pParent);
    m_Integral->Create(m_hWnd);
    m_Integral->MoveWindow(&rc);
    m_Integral->ShowWindow(SW_SHOWNORMAL) ;

    //создаем объект диалога маски пальцев
    m_Mashtab = new CMashtab(pParent);
    m_Mashtab->Create(m_hWnd);
    m_Mashtab->MoveWindow(&rc);
    m_Mashtab->ShowWindow(SW_HIDE);

    //создаем объект диалога настройки цветов фильтра
    m_ColorSet = new CColourSet(pParent);
    m_ColorSet->Create(m_hWnd);
    m_ColorSet->ModifyStyle(0, WS_TABSTOP | WS_EX_CONTROLPARENT);
    m_ColorSet->MoveWindow(&rc);
    m_ColorSet->ShowWindow(SW_HIDE);
    return true;
}

LRESULT w32View::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
//    ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
    int cur_pos;
    cur_pos = m_TabType.GetCurSel();
    switch(cur_pos)
    {
    case 0:            // активна вкладка с интегральным диалогом
        m_Integral->Invalidate();
        break;
    case 1:            // активна вкладка с диалогом маски пальцев
        m_Mashtab->Invalidate();
        break;
    case 2:            // активна вкладка с диалогом выбора цветов
        m_ColorSet->Invalidate();
        break;
    }
    
        bHandled = FALSE;
    return 0;
}  

LRESULT _w32View::OnNotify(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
   ATLASSERT(::IsWindow(m_hWnd));
   NMHDR* pNMHDR = (NMHDR*)lParam;

       switch(pNMHDR->code)
       {
       case TCN_SELCHANGING:
           break;
       case TCN_SELCHANGE:
            int cur_sel = m_TabType.GetCurSel();
            switch(cur_sel)
            {
            case 0:
                m_Mashtab->ShowWindow(SW_HIDE);
                m_ColorSet->ShowWindow(SW_HIDE);
                m_Integral->ShowWindow(SW_SHOW);
                break;
            case 1:
                m_Integral->ShowWindow(SW_HIDE);
                m_ColorSet->ShowWindow(SW_HIDE);
                m_Mashtab->ShowWindow(SW_SHOW);
                break;
            case 2:
                m_Integral->ShowWindow(SW_HIDE);
                m_Mashtab->ShowWindow(SW_HIDE);
                m_ColorSet->ShowWindow(SW_SHOW);
                break;
            default:
                m_Integral->ShowWindow(SW_HIDE);
                m_Mashtab->ShowWindow(SW_HIDE);
                m_ColorSet->ShowWindow(SW_HIDE);
                break;
            }
            break;
       }
       Invalidate(FALSE);

    return 0;
}


Попытаюсь весь мустор посторонний выкинуть, все к делу не относящееся, чтобы собрать новый проект чисто для проверки отрисовки.
Per aspera ad astra
Re[13]: Проблемы с перерисовкой, хотя OnPaint() есть
От: SaloS http://salos.narod.ru/
Дата: 28.04.05 05:30
Оценка:
Здравствуйте, Darked, Вы писали:

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


D> В обработчике WM_ERASEBKND у меня стоит только return 1, что убрало перерисовку фона, а соотвественно и флики (по — крайней мере в данном случае).

В этом случае лучше использовать стили WS_CLIPCHILDREN | WS_CLIPSIBLINGS. С помощью их можно запретить перерисовку окна по детьми, что должно помочь (в твоем случае, но не всегда)

D>
D>// функция создания вклодок
D>bool Cw32View::createTabs(void)
D>{
D>    CString str;    
D>    RECT rec;

D>    CWindow tab = CWindow(GetDlgItem(IDC_TAB_TYPE));
D>//    tab.ModifyStyle(0,WS_EX_CONTROLPARENT);

tab это окно СTabCtrl или что?
D>    tab.GetClientRect(&rec);

D>    m_TabType.Create(tab.m_hWnd, &rec , NULL, TCS_TABS |TCS_RAGGEDRIGHT | WS_CHILD | WS_VISIBLE , 0, 0U, NULL);

Что такое m_TabType — это тоже какой-то CTabCtrl, по стилям вроде он, но непонятно
    
D>    TC_ITEM TabCtrlItem = {0};
D>    TabCtrlItem.mask = TCIF_TEXT;
D>    _ASSERT(str.LoadString(IDS_STRING10271)) ;
D>    TabCtrlItem.cchTextMax = str.GetLength();
D>    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

D>    TabCtrlItem.iImage = -1;                
D>    m_TabType.InsertItem( 0, &TabCtrlItem );

D>    _ASSERT(str.LoadString(IDS_STRING10272)) ;
D>    TabCtrlItem.cchTextMax = str.GetLength();
D>    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

D>    TabCtrlItem.iImage = -1;                
D>    m_TabType.InsertItem( 1, &TabCtrlItem );

D>    m_TabType.SetCurSel(0);
D>    m_TabType.ShowWindow (SW_SHOW);

    
D>    RECT rc ;
D>    m_TabType.GetWindowRect(&rc) ; 
D>    m_TabType.AdjustRect(FALSE, &rc);
D>    ScreenToClient(&rc) ;

D>    //создаем объект интегрального диалога
D>    m_Integral = new CIntegral(pParent);
D>    m_Integral->Create(m_hWnd);

Если эта вкладка таба, то почему она создается не на CTabCtrl, а на родительском окне(Cw32View)
D>    m_Integral->MoveWindow(&rc);

Почему бы тебе сразу не установить rect прямо в Create
D>    m_Integral->ShowWindow(SW_SHOWNORMAL) ;

D>    //создаем объект диалога маски пальцев
D>    m_Mashtab = new CMashtab(pParent);
D>    m_Mashtab->Create(m_hWnd);
D>    m_Mashtab->MoveWindow(&rc);
D>    m_Mashtab->ShowWindow(SW_HIDE);

D>    //создаем объект диалога настройки цветов фильтра
D>    m_ColorSet = new CColourSet(pParent);

Если эта вкладка таба, то почему она создается не на CTabCtrl, а на родительском окне (Cw32View), для нее нет соотвествующего таба.
D>    m_ColorSet->Create(m_hWnd);
D>    m_ColorSet->ModifyStyle(0, WS_TABSTOP | WS_EX_CONTROLPARENT);
D>    m_ColorSet->MoveWindow(&rc);
D>    m_ColorSet->ShowWindow(SW_HIDE);
D>    return true;
D>}

D>LRESULT w32View::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
D>{
D>//    ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
D>    int cur_pos;
D>    cur_pos = m_TabType.GetCurSel();

Если я правильно понял по коду, ты добавляешь только 2 вкладки, а здесь ты проверяешь 3
D>    switch(cur_pos)
D>    {
D>    case 0:            // активна вкладка с интегральным диалогом

Invalidate в OnPaint, оригинально-с . Вообще так не делают. Если что изменилось, то нужно перерисовывать то что изменилось, а не в перерисовке окна вызывать перерисовку child'а. Если тебе нужно перерисовать child, то перерисовывай только его.
D>        m_Integral->Invalidate();
D>        break;
D>    case 1:            // активна вкладка с диалогом маски пальцев
D>        m_Mashtab->Invalidate();
D>        break;
D>    case 2:            // активна вкладка с диалогом выбора цветов
D>        m_ColorSet->Invalidate();
D>        break;
D>    }
    
D>        bHandled = FALSE;
D>    return 0;
D>}  

D>LRESULT _w32View::OnNotify(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
D>{
D>   ATLASSERT(::IsWindow(m_hWnd));
D>   NMHDR* pNMHDR = (NMHDR*)lParam;

D>       switch(pNMHDR->code)
D>       {
D>       case TCN_SELCHANGING:
D>           break;
D>       case TCN_SELCHANGE:
D>            int cur_sel = m_TabType.GetCurSel();
D>            switch(cur_sel)
D>            {
D>            case 0:
D>                m_Mashtab->ShowWindow(SW_HIDE);
D>                m_ColorSet->ShowWindow(SW_HIDE);
D>                m_Integral->ShowWindow(SW_SHOW);
D>                break;
D>            case 1:
D>                m_Integral->ShowWindow(SW_HIDE);
D>                m_ColorSet->ShowWindow(SW_HIDE);
D>                m_Mashtab->ShowWindow(SW_SHOW);
D>                break;
D>            case 2:
D>                m_Integral->ShowWindow(SW_HIDE);
D>                m_Mashtab->ShowWindow(SW_HIDE);
D>                m_ColorSet->ShowWindow(SW_SHOW);
D>                break;

Зачем делать одно и тоже при различных значениях. если тебе нужно сделать подобное можно было бы написать
case 0:
case 1:
case 2:
Ля-ля-ля три рубля
D>            default:
D>                m_Integral->ShowWindow(SW_HIDE);
D>                m_Mashtab->ShowWindow(SW_HIDE);
D>                m_ColorSet->ShowWindow(SW_HIDE);
D>                break;
D>            }
D>            break;
D>       }

Следующая строчка ненужна, так как установка окна из невидимого состояния в видимое автоматически вызывает перерисовку, и именно из-за этого у тебя и были флики !!!
D>       Invalidate(FALSE);

D>    return 0;
D>}
D>


Что касается невидимости, я просто думал, что ты обрабатываешь WM_SIZE не проверяя minimize окно или нет, и запоминаешь размер окна, которое было минимизировано, соотвественно там были неправильные координаты.
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[14]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 28.04.05 07:37
Оценка:
Здравствуйте, SaloS, Вы писали:

// функция создания вклодок
bool Cw32View::createTabs(void)
{
    CString str;    
    RECT rec;

    CWindow tab = CWindow(GetDlgItem(IDC_TAB_TYPE));
//    tab.ModifyStyle(0,WS_EX_CONTROLPARENT);
        tab.GetClientRect(&rec);

Этим я хотел просто получить координаты CTabCtrl, который брошен на форму, что бы в этих координатах потом создать свой CTabCtrl.
  m_TabType.Create(tab.m_hwnd, &rec , NULL, TCS_TABS |TCS_RAGGEDRIGHT | WS_CHILD | WS_VISIBLE , 0, 0U, NULL);

Что, как я теперь понял, есть большая глупость создавать таб контрол во временном окне. Сейчас это выглядит вот так:
         m_TabType.Attach(GetDlgItem(IDC_TAB_TYPE));



SS>tab это окно СTabCtrl или что?

SS>
D>>    tab.GetClientRect(&rec);

D>>    m_TabType.Create(tab.m_hWnd, &rec , NULL, TCS_TABS |TCS_RAGGEDRIGHT | WS_CHILD | WS_VISIBLE , 0, 0U, NULL);
SS>

SS>Что такое m_TabType — это тоже какой-то CTabCtrl, по стилям вроде он, но непонятно
m_TabType — это и есть мой основной таб-контрол.

SS>
    
D>>    TC_ITEM TabCtrlItem = {0};
D>>    TabCtrlItem.mask = TCIF_TEXT;
D>>    _ASSERT(str.LoadString(IDS_STRING10271)) ;
D>>    TabCtrlItem.cchTextMax = str.GetLength();
D>>    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

D>>    TabCtrlItem.iImage = -1;                
D>>    m_TabType.InsertItem( 0, &TabCtrlItem );

D>>    _ASSERT(str.LoadString(IDS_STRING10272)) ;
D>>    TabCtrlItem.cchTextMax = str.GetLength();
D>>    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

D>>    TabCtrlItem.iImage = -1;                
D>>    m_TabType.InsertItem( 1, &TabCtrlItem );

D>>    m_TabType.SetCurSel(0);
D>>    m_TabType.ShowWindow (SW_SHOW);

    
D>>    RECT rc ;
D>>    m_TabType.GetWindowRect(&rc) ; 
D>>    m_TabType.AdjustRect(FALSE, &rc);
D>>    ScreenToClient(&rc) ;

D>>    //создаем объект интегрального диалога
D>>    m_Integral = new CIntegral(pParent);
D>>    m_Integral->Create(m_hWnd);
SS>

SS>Если эта вкладка таба, то почему она создается не на CTabCtrl, а на родительском окне(Cw32View)
Тут я понял косяк, сейчас сделал вот так:

        RECT rc ;
    m_TabType.GetWindowRect(&rc) ; 
    m_TabType.AdjustRect(FALSE, &rc);
    ScreenToClient(&rc) ;

    m_Integral = new CIntegral(pParent);
    m_Integral->Create(m_TabType.m_hWnd, rc);
    m_Integral->ShowWindow(SW_SHOWNORMAL) ;

Но почему — то никак не могу заставить их появлятся в начале вкладки, диалог вставляется в нижнем углу, и естесвенно весь не влазит. Сейчас пытаюсь победить. Интересно, что как бы я не получал rc, какими бы функциями, даже если вообще не получаю, появляются диалоги все равно в нижнем углу.

SS>
D>>    m_ColorSet->Create(m_hWnd);
D>>    m_ColorSet->ModifyStyle(0, WS_TABSTOP | WS_EX_CONTROLPARENT);
D>>    m_ColorSet->MoveWindow(&rc);
D>>    m_ColorSet->ShowWindow(SW_HIDE);
D>>    return true;
D>>}

D>>LRESULT w32View::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
D>>{
D>>//    ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
D>>    int cur_pos;
D>>    cur_pos = m_TabType.GetCurSel();
SS>

SS>Если я правильно понял по коду, ты добавляешь только 2 вкладки, а здесь ты проверяешь 3
3-ю я добавляю динамически потом:

if(Fl_Active)
    {
        _ASSERT(str.LoadString(IDS_COLOR_SET)) ;
        TabCtrlItem.cchTextMax = str.GetLength();
        TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

        TabCtrlItem.iImage = -1;                
        m_TabType.InsertItem(2, &TabCtrlItem);
        m_TabType.SetCurSel(2);
        m_Integral->ShowWindow(SW_HIDE) ;
        m_Mashtab->ShowWindow(SW_HIDE) ;
        m_ColorSet->ShowWindow(SW_SHOWNORMAL) ;
    }
    else
    {
        m_TabType.SetCurSel(0);
        m_TabType.DeleteItem(2);        
        m_Integral->ShowWindow(SW_SHOWNORMAL) ;
        m_Mashtab->ShowWindow(SW_HIDE) ;
        m_ColorSet->ShowWindow(SW_HIDE) ;
    }


SS>
D>>    switch(cur_pos)
D>>    {
D>>    case 0:            // активна вкладка с интегральным диалогом
SS>


SS>
D>>        m_Integral->Invalidate();
D>>        break;
D>>    case 1:            // активна вкладка с диалогом маски пальцев
D>>        m_Mashtab->Invalidate();
D>>        break;
D>>    case 2:            // активна вкладка с диалогом выбора цветов
D>>        m_ColorSet->Invalidate();
D>>        break;
D>>    }
    
D>>        bHandled = FALSE;
D>>    return 0;
D>>}  

D>>LRESULT _w32View::OnNotify(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
D>>{
D>>   ATLASSERT(::IsWindow(m_hWnd));
D>>   NMHDR* pNMHDR = (NMHDR*)lParam;

D>>       switch(pNMHDR->code)
D>>       {
D>>       case TCN_SELCHANGING:
D>>           break;
D>>       case TCN_SELCHANGE:
D>>            int cur_sel = m_TabType.GetCurSel();
D>>            switch(cur_sel)
D>>            {
D>>            case 0:
D>>                m_Mashtab->ShowWindow(SW_HIDE);
D>>                m_ColorSet->ShowWindow(SW_HIDE);
D>>                m_Integral->ShowWindow(SW_SHOW);
D>>                break;
D>>            case 1:
D>>                m_Integral->ShowWindow(SW_HIDE);
D>>                m_ColorSet->ShowWindow(SW_HIDE);
D>>                m_Mashtab->ShowWindow(SW_SHOW);
D>>                break;
D>>            case 2:
D>>                m_Integral->ShowWindow(SW_HIDE);
D>>                m_Mashtab->ShowWindow(SW_HIDE);
D>>                m_ColorSet->ShowWindow(SW_SHOW);
D>>                break;
SS>

SS>Зачем делать одно и тоже при различных значениях. если тебе нужно сделать подобное можно было бы написать
SS>case 0:
SS>case 1:
SS>case 2:
SS>Ля-ля-ля три рубля
SS>
D>>            default:
D>>                m_Integral->ShowWindow(SW_HIDE);
D>>                m_Mashtab->ShowWindow(SW_HIDE);
D>>                m_ColorSet->ShowWindow(SW_HIDE);
D>>                break;
D>>            }
D>>            break;
D>>       }
SS>

Там не одно и тоже, там разное сочетание SW_HIDE и SW_SHOW.

Огромное спасибо за подсказки!
Per aspera ad astra
Re[14]: Проблемы с перерисовкой, хотя OnPaint() есть
От: Darked  
Дата: 28.04.05 10:18
Оценка:
Вообщем, заработало

bool Cw32View::createTabs(void)
{
    CString str;    

    m_TabType.Attach(GetDlgItem(IDC_TAB_TYPE));    

    TC_ITEM TabCtrlItem = {0};
    TabCtrlItem.mask = TCIF_TEXT;
    _ASSERT(str.LoadString(IDS_STRING10271)) ;
    TabCtrlItem.cchTextMax = str.GetLength();
    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

    TabCtrlItem.iImage = -1;                
    m_TabType.InsertItem( 0, &TabCtrlItem );    // создаем первую вкладку для диалога CIntegral

    _ASSERT(str.LoadString(IDS_STRING10272)) ;
    TabCtrlItem.cchTextMax = str.GetLength();
    TabCtrlItem.pszText = (LPTSTR) (LPCTSTR) str;

    TabCtrlItem.iImage = -1;                
    m_TabType.InsertItem( 1, &TabCtrlItem );    // создаем вторую вкладку для диалога CMashtab

    m_TabType.SetCurSel(0);
        
    RECT rc ;
    m_TabType.GetClientRect(&rc) ; 
    m_TabType.AdjustRect(FALSE, &rc);    // выравниваем содержимое, чтобы вкладки не залезали на названия

    //создаем объект интегрального диалога
    m_Integral = new CIntegral(pParent);
    m_Integral->Create(m_TabType.m_hWnd);
    m_Integral->MoveWindow(&rc);
    m_Integral->ShowWindow(SW_SHOWNORMAL) ;

    //создаем объект диалога маски пальцев
    m_Mashtab = new CMashtab(pParent);
    m_Mashtab->Create(m_TabType.m_hWnd);
    m_Mashtab->MoveWindow(&rc);
    m_Mashtab->ShowWindow(SW_HIDE);

    //создаем объект диалога настройки цветов фильтра
    m_ColorSet = new CColourSet(pParent);
    m_ColorSet->Create(m_TabType.m_hWnd);
    m_ColorSet->MoveWindow(&rc);
    m_ColorSet->ShowWindow(SW_HIDE);

    m_TabType.ShowWindow (SW_SHOW);
    return true;
}

Сразу m_ColorSet->Create(m_TabType.m_hWnd, rc); — не получается, вкладка заезжает на название .
Перерисовка:

LRESULT CColourSet::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    CBrush br;
    RECT rcRect;
    PAINTSTRUCT m_ps;
    HDC m_hDC;

    m_hDC = ::BeginPaint(m_hWnd, &m_ps);
    drawColRect(m_hDC);
    ::EndPaint(m_hWnd, &m_ps);

    m_ClrLine.GetClientRect(&rcRect);
//    ClientToScreen(&rcRect);
    m_hDC = ::BeginPaint(m_ClrLine.m_hWnd, &m_ps);
    br.CreateSolidBrush(line);
    ::FillRect(m_hDC, &rcRect, br.m_hBrush);
    ::EndPaint(m_ClrLine.m_hWnd, &m_ps);

    br.DeleteObject();

m_hDC = ::BeginPaint(m_ClrPit.m_hWnd, &m_ps);
    br.CreateSolidBrush(pit);
    m_ClrPit.GetClientRect(&rcRect);
    ::FillRect(m_hDC, &rcRect, br.m_hBrush);
    ::EndPaint(m_ClrLine.m_hWnd, &m_ps);
        
    return 0;
}


Еще раз большое спасибо!
Per aspera ad astra
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.