Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как изменить цвет рамки приложения?_ WinAPI & Visual C++  (Прочитано 24679 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 25-11-2005 11:25 » 

Господа, вопрос:

есть приложение типа эксплорер. Как при старте (и вообще) поменять цвет рамки?
Попробовала следующее - не работает : ;-(

Код:

void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting

CRect rect;

CPen* pPenOld = NULL, penNew;

if (this)
{
penNew.CreatePen(PS_SOLID, 3, RGB(255,0,0));
pPenOld = dc.SelectObject(&penNew);

this->GetWindowRect(&rect);

// dc.DrawEdge(&rect, EDGE_BUMP, BF_RECT);  // первая попытка

dc.Rectangle(&rect);   // вторая попытка

dc.SelectObject(pPenOld);
}
}



Может, кто-то знает? Горит...  Так больше нельзя...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
ChaoticCube
ChaoticCube
Помогающий

ru
Offline Offline
Пол: Мужской
ChaoticCube


« Ответ #1 : 25-11-2005 11:32 » 

Попробуй так, как MSDN рекомендует... Легкие преобразования кода и все должно получится.


Код:
void CMainFrame::OnDraw(CDC* pDC)
{
   // Create and select a solid blue brush.
   CBrush brushBlue(RGB(0, 0, 255));
   CBrush* pOldBrush = pDC->SelectObject(&brushBlue);

   // Create and select a thick, black pen.
   CPen penBlack;
   penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
   CPen* pOldPen = pDC->SelectObject(&penBlack);

   // Get the client rectangle.
   CRect rect;
   GetClientRect(rect);

   // Shrink the rectangle 20 pixels in each direction.
   rect.DeflateRect(20, 20);

   // Draw a thick black rectangle filled with blue.
   pDC->Rectangle(rect);

   // Put back the old objects.
   pDC->SelectObject(pOldBrush);
   pDC->SelectObject(pOldPen);
}
Записан

Сила ночи, сила дня - одинакого фигня....
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #2 : 25-11-2005 11:35 » 

Malaja, проще говоря - никак. Цвета идут из системы. Можно поменять цвет сразу всез окон. Остаётся только одно - рисовать всё окно самому.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #3 : 25-11-2005 11:46 » 

ChaoticCube,

попробовала - к сожалению, не получается...

Джон,

что ты имеешь в виду? Что ты подразумеваешь под рисованием окна?
Я как раз это и попробовала сделать - не выходит. Попробовала уже FillRect - реакции никакой... Такое впечатление, что либо я в принципе что-то делаю не так, либо координаты прямоугольника неверны...

Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
ChaoticCube
ChaoticCube
Помогающий

ru
Offline Offline
Пол: Мужской
ChaoticCube


« Ответ #4 : 25-11-2005 11:47 » 

>Джон.
Как я понимаю о прорисовке окна и идет речь. Надо просто провести стандартную прорисовку, а после нее поверх наложить то что рисуем.

Я бы попробовал так. Наверняка есть ошибки - но отлаживать и проверять времени счас нет.

Код:
void CMainFrame::OnPaint() 
{
       __super::OnPaint();

       CDC* pDC = this->GetDC(); // device context for painting

       if (pDC)
      {
            // Create and select a solid blue brush.           - тут создашь то что тебе надо
            CBrush brushBlue(RGB(0, 0, 255));
            CBrush* pOldBrush = pDC->SelectObject(&brushBlue);

            // Create and select a thick, black pen.            - аналогично
            CPen penBlack;
            penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
            CPen* pOldPen = pDC->SelectObject(&penBlack);

            // Get the client rectangle.
           CRect rect;
           GetWindowRect(rect);

           // Shrink the rectangle 1 pixels in each direction.
           rect.DeflateRect(1, 1);

           // Draw a thick black rectangle filled with blue.
           pDC->Rectangle(rect);

          // Put back the old objects.
          pDC->SelectObject(pOldBrush);
         pDC->SelectObject(pOldPen);
       }
}
[\code]

>Malaja
 Так пробовала?
Записан

Сила ночи, сила дня - одинакого фигня....
ChaoticCube
ChaoticCube
Помогающий

ru
Offline Offline
Пол: Мужской
ChaoticCube


« Ответ #5 : 25-11-2005 11:50 » 

>Malaja
В твоем коде следующая вещь мне не понятна:
CPaintDC dc(this); // device context for painting - почему не GetDC() ?
Записан

Сила ночи, сила дня - одинакого фигня....
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #6 : 25-11-2005 11:57 » 

ChaoticCube,

если я с помощью визарда генерирую сообщение OnPaint() для класса CMainFrame, то получаю подготовленную строку CPaintDC dc(this).
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #7 : 25-11-2005 12:01 » 

ChaoticCube,

пардон, не ответила на вопрос: попробовала - никакой реакции...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #8 : 25-11-2005 14:14 » 

Джон,

как обычно - пришли час назад и сказали, что надо было еще вчера Ага
Я уже сказала, что это дело весьма непростое, посему предложила поменять BackgroundColor в правом View (смысл - одинаковое приложение стартует при показе 2 видов инфы. Посему они вдруг захотели,чтобы это было видно не только из названия окна, но и с помощью другого цвета).
С рамкой толком не получается - я дошла до того, что при старте на мгновение появляется мой цвет, а потом полируется стандартным цветом винды.

Сейчас смотрю, как можно изменить BackgroundColor, но это пока тоже не выходит...
Т.е. в созданном мной для теста примере все ок, а в реальном - пшик Ага
Сейчас ищу, где и что не так.

Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 25-11-2005 14:26 » 

Значица так - быстро не получится - всё что вы делаете - правильно. Можно только добавить - ScreenToClient(rect); после GetWindowRect(rect);
Только вы забываете об одном факте, что это MFC объекты, которые рисуют себя сами - те всё что вы рисуете - зарисовывается нафиг другими окнами - View, Splitter, Toolbar, Statusbar и тд и тп
Поэтому я и сказал - рисовать самому - полностью.
Про "ещё вчера" они могут это забыть. "Такие вопросы с кандачка не решаются".
Чтобы фон View изменить - надо перерерисовывать фон контрола - какие там у тебя? List/TreeCtrl?
Тебя ща можно по хэнди достать? Так оперативней будет.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 25-11-2005 15:22 » 

Код:
void CMyView::OnDraw(CDC* pDC)
{

CRect rcInvalid;
if (pDC->GetClipBox(rcInvalid) == NULLREGION)  // просто экономим если не надо
return;
CRect rcClient;
GetClientRect(rcClient);

        ....

зы В rcInvalid нужный тебе прямоугольник
« Последнее редактирование: 25-11-2005 15:25 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ChaoticCube
ChaoticCube
Помогающий

ru
Offline Offline
Пол: Мужской
ChaoticCube


« Ответ #11 : 25-11-2005 16:06 » 

Значица так - быстро не получится - всё что вы делаете - правильно. Можно только добавить - ScreenToClient(rect); после GetWindowRect(rect);
Только вы забываете об одном факте, что это MFC объекты, которые рисуют себя сами - те всё что вы рисуете - зарисовывается нафиг другими окнами - View, Splitter, Toolbar, Statusbar и тд и тп
Поэтому я и сказал - рисовать самому - полностью.
Про "ещё вчера" они могут это забыть. "Такие вопросы с кандачка не решаются".
Чтобы фон View изменить - надо перерерисовывать фон контрола - какие там у тебя? List/TreeCtrl?
Тебя ща можно по хэнди достать? Так оперативней будет.

Джон, немного теории. Насколько я понимаю - Малой нужена именно рамка. Те объекты что рисуются поверх MainFrame - рисуются во-первых на клиентской части, а во-вторых перерисовка осуществляется только для областей этих объектов.

Признаюсь, меня ставит в тупик что код выше написанный не работает. У меня возникает только идея по этому поводу - что он фактически находится не в том месте. И должен быть вызван после стандартной прорисовки всего окна.

Я в чем то ошибаюсь?

К сожалению, в данный момент на работе - и не располагаю временем на эксперименты. Но решения данной задачи мне весьма интересны.
Записан

Сила ночи, сила дня - одинакого фигня....
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 25-11-2005 16:33 » 

ChaoticCube, дык все мы на работе. Улыбаюсь А кому ща легко?  Ага ТОже бы с удовольствием поигрался.

Короче проблема заключалась в след. клиенту хотелось чтобы при разные инстанции проги при разных данных чем-нибудь отличались. Рамка  в даном случае рисуется "стилем" окна.
Простой ON_WMPAINT её не перерисуешь. То что код не находится "на месте"  - отчасти правильно.
Только как решить подобную проблему? Изменять объекты MFC? Или сделать своё окно? Похоронив тем самым Doc/View архитектуру?

А твой код работает на 100% (за исключением конечно смещения относительно координат экрана).
Чтобы увидеть доказательства этому (и тому что я говорю) сделай например вместо pDC->Rectangle(rect);
просто FillSolidRect красного цвета - чтоб лучше было видно. Если комп не слишком быстрый, то ты увидишь моргание красного прямоугольника. Если этого не достаточно - выключи все контролы - ToolBar, StatusBar и все docking окошки. Потом,  если у тебя есть View - перепиши в нём WM_ERASEBACKGROUND  - всё что она должна делать, retun FALSE;
После этого ты увидишь действительно красный прямоугольник, по всему окну НО! 3D - рамка останется.
Чтобы этого не происходило необходимо полностъю рисовать всё самому. ЧТо очень гемморно и в сушествующем проекте за пару часов не сделаешь. Тем более, что там ещё и Splitter задействован.
А готово всё должно было быть к 17:00 (19:00 Москвы)
Короче компромисный вариант был найден - изменять цвет правого View (public CScrollView) в зависимости от условий. У Malaja была только проблема с пересчётом клиентского прямоугольника в зависимости от положения скроллера. Ну вроде бы всё обошлось.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #13 : 25-11-2005 18:04 » 

Ребята,

еще раз всем огромное спасибо!
Заморочку в проекте я нашла и теперь все работает (я имею в виду цвет правого окна).
Насчет рамки - действительно интересно покопаться, но на это нужно время.
Если у кого-то получится - с удовольствием посмотрю (если дадут Ага )
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
zubr
Гость
« Ответ #14 : 25-11-2005 18:11 » 

Сдается мне перерисовку рамки окна надо делать не в WM_PAINT, а в WM_NCPAINT.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #15 : 25-11-2005 18:18 » 

Теоретичечески можно это сделать, если перехватывать сообшение, которое идет на прорисовку не клиентской части окна WM_NCPAINT
Код примерно будет выглядеть так:
Код:
case WM_NCPAINT:
    DefWindowProc(hwnd, msg, wParam, lParam);   //Тута отдаем на прорисовку не клиентской части
                                  //Кстати можно похитрить и уменьшить регион прорисовки
                                 // Который идет в wParam
    DC=GetDC(hwnd);
   ...........................                                     //Рисуем свое
   ReleaseDC(hwnd, DC);
   break;
« Последнее редактирование: 25-11-2005 18:19 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
zubr
Гость
« Ответ #16 : 25-11-2005 20:13 » 

Вместо GetDC надо юзать GetWindowDC, тогда получится, я когдато в Delphi это реализовывал через API.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines