Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не перекрашиваются контролы, обрабатываю WM_CTLCOLOR 
:(
    Опции темы
takedo
Дата 9.12.2005, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



Dreamer_0x01
Цитата
Но вот если присмотреться к стандартной кнопки, то при ее нажимании текст кнопки нажимается вместе с ней. А тут он остается неподвижным.
Я же говорил, что надо доработать smile -в зависимости от состояния меняю координаты начала текста и др. и кнопка начинает вести себя как и все другие. А вот использовать в таком случае OnPaint по моему не верно, у меня так даже и не заходит туда - все в DrawItem smile

Earnest Я вот и спрашивал
Цитата
Кто знает как нарисовать объемный эллипс? В том смысле, честь ли функция типа ::DrawFrameControl только рисующая эллипс или произвольный многоугольник. Можно и самому отрисовывать, но с объемом проблемы. 
- вот и вы до этого же дошли smile Dreamer_0x01 по моему этого то и не хватает...


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
Earnest
Дата 9.12.2005, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Лучше бы все делать в одном месте, т.е. в DrawItem. Кто тебе мешает заливать фон здесь? В этой функции можешь делать все то же самое - вызываешь какой-нибудь FillRect, и все.
Конечно, пример - это только пример, далеко не полный.
При нажатии текст кнопки действительно надо сдвигать, примерно на 1,1 вниз по диагонали.
Не забудь после отрисовки состояние DC поменять на исходное - MSDN на этом очень настаивает.
Я обычно, чтобы не парится с востановлением всего, что наменяла, использую SaveDC - RestoreDC. Еще удобнее - завернуть все в классик:
Код

class CDCState
{
public:
   CDCState (CDC& dc):  m_dc (dc) {  m_nState = m_dc.SaveDC(); }
   ~CDCState()   { m_dc.RestoreDC (m_nState); }

private:
   CDC& m_dc;
   int m_nState;
};

#define SAVE_DC_STATE(dc) CDCState _dcState(dc)

Ставишь в начала функции SAVE_DC_STATE() и больше ни о чем не заботишься.
Добавлено @ 09:08
takedo, на пару минут опередил smile



--------------------
...
PM   Вверх
takedo
Дата 9.12.2005, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



Я вот так сделал, много лишнего, но это вырезка из кода, думаю не страшно smile
Код

void CMButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

    if(m_draw)return;
    ::InterlockedExchange(&m_draw,1);//после изменения
    peek(&dat);
    BYTE nWnd = dat.r_N(); 
    CRect rect(lpDrawItemStruct->rcItem);
    CRect rectclient;
    CRect rect_dt;//по пожеланиям Ромы
    int cx = GetSystemMetrics(SM_CXEDGE);
    int cy = GetSystemMetrics(SM_CYEDGE);
    CDC dc;

    rect.bottom-=cy+1;
    rect.right-=cx+1;
    rect.top+=cy+1;
    rect.left+=cx+1;
    rectclient = rect;

    dc.Attach(lpDrawItemStruct->hDC);
    CPen mypen;
    CPen* oldpen;
    COLORREF crText,crBk,crPen,crBrush,crTextOld,crBkOld;
    
    CBrush* oldbrush;
    CString strText;

    GetColor(&crText,&crBk,&crPen,&crBrush);

    
     mypen.CreatePen(PS_SOLID,1,crPen);
     CBrush mybrush(crBrush);
     
     oldpen = dc.SelectObject(&mypen);
     oldbrush = dc.SelectObject(&mybrush);
     crTextOld = dc.SetTextColor(crText);
     crBkOld = dc.SetBkColor(crBk);

   UINT uStyle = DFCS_BUTTONPUSH;
   // This code only works with buttons.
   ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);

   if (lpDrawItemStruct->itemState & ODS_SELECTED)
   {
      uStyle |= DFCS_PUSHED;
      rectclient.left+=cx;
      rectclient.top+=cy;
      rectclient.right+=cx;
      rectclient.bottom+=cy;
     
   }else

   // Draw the button frame.
   dc.Rectangle(&rectclient);

   dc.DrawFrameControl(&lpDrawItemStruct->rcItem,lpDrawItemStruct->CtlType,uStyle);   
   
   dc.Rectangle(&rectclient);

   strText.Format(_T("№ %d"),nWnd);
  

   dc.DrawText(strText,&rectclient,DT_VCENTER|DT_CENTER);
   
   rectclient.top+= (rectclient.bottom - rectclient.top)/3;


   rect_dt = rectclient; 
   rect_dt.right = dc.GetTextExtent(_T(" Out:")).cx;
   strText.Format(_T(" In:"));

   dc.DrawText(strText,&rect_dt,DT_VCENTER|DT_RIGHT);

   strText.Format(_T("%10d "),dat.r_InCount());
   dc.DrawText(strText,&rectclient,DT_VCENTER|DT_RIGHT);
   
   rectclient.top+= (rectclient.bottom - rectclient.top)/2;

   rect_dt.top = rectclient.top;

   strText.Format(_T(" Out:"));

   dc.DrawText(strText,&rect_dt,DT_VCENTER|DT_RIGHT);

   strText.Format(_T("%10d "),dat.r_OutCount());
   dc.DrawText(strText,&rectclient,DT_VCENTER|DT_RIGHT);
   

   dc.SetTextColor(crTextOld);
   dc.SetBkColor(crBkOld);
   dc.SelectObject(oldpen);
   dc.SelectObject(oldbrush);

   dc.Detach();
    

   ::InterlockedExchange(&m_draw,0);
   return;
} 



--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
takedo
Дата 9.12.2005, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



Earnest
посмотрел SaveDC так в мсдн говорят, что все текущее состояние сохраняется в "context stack" - это куда, можно узнать? Спрашиваю потому, что как и обычно твой классик - весьма удобен, но вот сомнения терзанули, а сколько может быть сохранено в этом контексте?


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
takedo
Дата 9.12.2005, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: нет
Всего: 3



Earnest
Я почему спросил, мотому что не понял в каком стеке? То есть у каждого DC есть свой стек? В который мы и записываем. Но вот какая мне проблема видится: есть функция обработчик1 и функция обработчик2 сообщения 1 и 2. В фукнции 1 мы сохраняем SaveDC(hdc), в это время, приходит сообщение, вызывающее обработчик 2, в котором мы тоже SaveDC(hdc). В итоге, если сохраняем в одно и то же место можем восстановить по Restore не то. Или как то возвращаемый SaveDC параметр влияет. Вот не могу этого понять smile


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
JoyEx
Дата 9.12.2005, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дядя
**


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

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



Цитата(takedo @ 9.12.2005, 09:32)
посмотрел SaveDC так в мсдн говорят, что все текущее состояние сохраняется в "context stack" - это куда, можно узнать?


Где-то в GDI-памяти, механизм стека для этих целей можно и самому сделать, но лучше не быть smile Самоделкиным.

SaveDC(hdc) ==> RestoreDC(hdc, -1) ведь очень удобно!

Цитата
сколько может быть сохранено в этом контексте

Пока SaveDC() не вернет 0

Цитата(takedo @ 9.12.2005, 12:05)
Но вот какая мне проблема видится: есть функция обработчик1 и функция обработчик2 сообщения 1 и 2. В фукнции 1 мы сохраняем SaveDC(hdc), в это время, приходит сообщение, вызывающее обработчик 2, в котором мы тоже SaveDC(hdc). В итоге, если сохраняем в одно и то же место можем восстановить по Restore не то. Или как то возвращаемый SaveDC параметр влияет.


Да-да, "возвращаемый SaveDC параметр" и нужен для того, чтобы не появился хаос:
RestoreDC(hdc, сюда его прописывай).


Это сообщение отредактировал(а) JoyEx - 9.12.2005, 16:15


--------------------
Если ты уже никого не боишься, значит ты самый страшный 
PM IM ICQ AOL YIM MSN   Вверх
Earnest
Дата 9.12.2005, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



JoyEx все правильно говорит.
takedo
Честно говоря, я не знаю, сколько состояний выдержит этот стек, не экспериментировала. Обычно я ставлю сохранение DC контекста в начале самой внешней функции отрисовки (которую Windows или MFC вызывают), а во внутренних уже не забочусь о том, что изменилось - внешняя функция, завершаясь, все подчистит.
Пользуюсь давно, проблем не было.



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


Терминатор
**


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

Репутация: 9
Всего: 12



А может, кто на пальцах пояснит, для чего вообще этот RestoreDC нужен? Только в MSDN просьба не отсылать, на английском не пойму...


--------------------
Нет ничего невозможного. Есть цели, и есть время и силы на их достижение.
PM ICQ   Вверх
JoyEx
Дата 10.12.2005, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дядя
**


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

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



Цитата(Dreamer_0x01 @ 10.12.2005, 15:25)
А может, кто на пальцах пояснит, для чего вообще этот RestoreDC нужен? Только в MSDN просьба не отсылать, на английском не пойму...

Нуууу... smile , Dreamer_0x01 , это типа smile ПоелИубериСамЗаСобой, а если серЪёзно, то все апишные ф-ции рисуют текущими карандашами (Pen) и т.п., а если ты не восстановишь (RestoreDC) этот карандаш, то кто-то (например, баз. класс) будет рисовать уже твоим карадашом.

Это сообщение отредактировал(а) JoyEx - 10.12.2005, 16:43


--------------------
Если ты уже никого не боишься, значит ты самый страшный 
PM IM ICQ AOL YIM MSN   Вверх
Earnest
Дата 12.12.2005, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Dreamer_0x01 @ 10.12.2005, 15:25)
А может, кто на пальцах пояснит, для чего вообще этот RestoreDC нужен?

Да ровно для того, чтобы не писать все эти многочисленные pDC->SelectObject(pOldPen) и не запоминать олд-пены.
Есть такая весьма распространенная ошибка: создаем в функции GDI-объект, выбираем его в контекст, по выходе из функции созданный объект удаляем, но забываем восстановить старый. Так вот, в этом случае GDI-объект вовсе не удаляется. Особенно в 98 это весело выглядит: пара минут работы, и все рисуется белым - кончились GDI-ресурсы, остались одни стандартные.
А когда пишешь более-менее сложный код, согласись, есть о чем думать, кроме того, чтобы запомнить, что ты там выбрал в контекст. В идеале - совсем об этом не заботиться. Вот для этого идеально подходит парочка SaveDC-RestoreDC.


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


 




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


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

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