Проблема! Есть окно, куда загружается Битмап. Поверх этого Битмапа cоздается еще одно окно (CWnd::Create(...)). И это, дочернее окно должно быть такого же фона, как и Битмап. Что делать?
Здравствуйте, SexMachine, Вы писали:
SM>Здравствуйте, IRINIC,
SM>Обработать сообщение WM_ERASEBKGND — в нем можно залить фон каким либо цветом, или даже вывести картинку.
Здравствуйте, IRINIC, Вы писали: SM>>Обработать сообщение WM_ERASEBKGND — в нем можно залить фон каким либо цветом, или даже вывести картинку.
IRI>Можно уточнить, каким образом?
Примерно вот так: (сам не проверял, но вроде бы ок. Украдено здесь)
BOOL CMYDialog::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CBitmap bmpBackground;
VERIFY( bmpBackground.LoadBitmap( IDB_BITMAP1) );
// Get the dimensions of the bitmap.
BITMAP bm;
bmpBackground.GetObject( sizeof(BITMAP), &bm );
// How big is the destination window?
RECT clientRect;
GetClientRect( &clientRect );
// Get the position to draw the upper
// left corner of the bitmap.
CPoint point( clientRect.left, clientRect.top );
// Get the width and height the bitmap
// needs to be drawn.
CSize size( clientRect.right, clientRect.bottom );
// Create a memory DC compatible with the window's DC.
CDC memDC;
VERIFY( memDC.CreateCompatibleDC( pDC ) );
// Select the background bitmap into the memory DC.
CBitmap* pOldBmp = memDC.SelectObject( &bmpBackground );
ASSERT( pOldBmp != NULL );
// StretchBlt the bitmap onto the window's background.
pDC->StretchBlt( point.x, point.y, size.cx, size.cy,
&memDC, 0, 0, bm.bmWidth-1, bm.bmHeight-1,
SRCCOPY );
// Select out the bitmap.
VERIFY( memDC.SelectObject( pOldBmp ) );
// Delete the bitmap that was loaded.
bmpBackground.DeleteObject();
return TRUE;
}
Здравствуйте, IRINIC, Вы писали:
IRI>Проблема! Есть окно, куда загружается Битмап. Поверх этого Битмапа cоздается еще одно окно (CWnd::Create(...)). И это, дочернее окно должно быть такого же фона, как и Битмап. Что делать?
А может, тебе нужно прозрачное окно? (со стилем WS_TRANSPARENT) — т.е. не заслоняет собой нижележащие окна, а рисуется поверх них после того, как они сами отрисовались.
Например, так себя ведёт GROUPBOX — контрол рамочки с надписью.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, IRINIC, Вы писали:
IRI>>Проблема! Есть окно, куда загружается Битмап. Поверх этого Битмапа cоздается еще одно окно (CWnd::Create(...)). И это, дочернее окно должно быть такого же фона, как и Битмап. Что делать?
К>А может, тебе нужно прозрачное окно? (со стилем WS_TRANSPARENT) — т.е. не заслоняет собой нижележащие окна, а рисуется поверх них после того, как они сами отрисовались. К>Например, так себя ведёт GROUPBOX — контрол рамочки с надписью.
В этом есть разумное зерно, но тогда будет серый цвет, так как прозрачность будет по отношению к родительскому окну, а не к Битмапу. Поэтому этот способ не подходит.
Здравствуйте, IRINIC, Вы писали: IRI>Нет, не помогает...
Не помогает от чего? Что происходит не так, как должно происходить?
Вызывается ли вообще функция? Может быть такое, что ты забыл внести новый элемент в карту сообщений?
Т.е. есть ли у тебя нечто подобное:
Здравствуйте, febus, Вы писали:
F>Не помогает от чего? Что происходит не так, как должно происходить? F>Вызывается ли вообще функция? Может быть такое, что ты забыл внести новый элемент в карту сообщений?
Мне же нужно удалять тот Битмап, который загружается. Нужно поверх него нарисовать окно, у которого фон будет такой же, как и цвет Битмапа. Окно создано (CWnd::Create(...)), а вот как цвет фона для него установить?
Re[7]: Помогите бедному ламеру поменять цвет фона
От:
Аноним
Дата:
26.09.06 02:36
Оценка:
Здравствуйте, IRINIC, Вы писали:
IRI>Здравствуйте, febus, Вы писали:
F>>Не помогает от чего? Что происходит не так, как должно происходить? F>>Вызывается ли вообще функция? Может быть такое, что ты забыл внести новый элемент в карту сообщений?
IRI>Мне же нужно удалять тот Битмап, который загружается. Нужно поверх него нарисовать окно, у которого фон будет такой же, как и цвет Битмапа. Окно создано (CWnd::Create(...)), а вот как цвет фона для него установить?
Курите
DWORD SetClassLong(HWND hWnd, int nIndex, LONG dwNewLong);
с параметром GCL_HBRBACKGROUND.
А ещё проще просто напишите в обработчике WM_ERASEBKGND заливку окна нужным цветом.
Здравствуйте, IRINIC, Вы писали:
К>>А может, тебе нужно прозрачное окно? (со стилем WS_TRANSPARENT) — т.е. не заслоняет собой нижележащие окна, а рисуется поверх них после того, как они сами отрисовались. К>>Например, так себя ведёт GROUPBOX — контрол рамочки с надписью.
IRI>В этом есть разумное зерно, но тогда будет серый цвет, так как прозрачность будет по отношению к родительскому окну, а не к Битмапу. Поэтому этот способ не подходит.
Ты же сам сказал про "поверх"... В конце концов, можно под прозрачное окно подложить ещё один STATIC с битмапом.
Или ты хочешь, чтобы родитель мог произвольному дочернему окну менять фон? Вот добавили на наш хитроумный диалог какой-нибудь EDITBOX, вуаля — и у него появился фон?
Тогда нужно субклассить и перекрывать WM_ERASEBACKGROUND. Но это — лотерейное занятие. Дело в том, что у каждого окна свои взгляды на то, как рисоваться в два приёма (WM_ERASEBKGND + WM_PAINT) — кто-то делает всё в первом обработчике, а кто-то всё (включая очистку фона) во втором.
Здравствуйте, Кодт, Вы писали:
К>Или ты хочешь, чтобы родитель мог произвольному дочернему окну менять фон? Вот добавили на наш хитроумный диалог какой-нибудь EDITBOX, вуаля — и у него появился фон? К>Тогда нужно субклассить и перекрывать WM_ERASEBACKGROUND. Но это — лотерейное занятие. Дело в том, что у каждого окна свои взгляды на то, как рисоваться в два приёма (WM_ERASEBKGND + WM_PAINT) — кто-то делает всё в первом обработчике, а кто-то всё (включая очистку фона) во втором.
А каким образом использовать WM_PAINT?
И вообще, какая разница между использованием WM_PAINT и WM_ERASEBKGND?
Здравствуйте, febus, Вы писали:
F>Здравствуйте, IRINIC, Вы писали: SM>>>Обработать сообщение WM_ERASEBKGND — в нем можно залить фон каким либо цветом, или даже вывести картинку.
IRI>>Можно уточнить, каким образом?
F>Примерно вот так: (сам не проверял, но вроде бы ок. Украдено [url=http://microsoft.ease.lsoft.com/scripts/wa-msn.exe?
Проблемно достать DC родительского окна, чтоб использовать их для WM_ERASEBKGND.
Здравствуйте, IRINIC, Вы писали:
IRI>А каким образом использовать WM_PAINT? IRI>И вообще, какая разница между использованием WM_PAINT и WM_ERASEBKGND?
Его никак не использовать. Эти события присылает оконный менеджер системы, когда сочёт нужным, что окну пора перерисоваться. А уже оконная процедура выполняет перерисовку (mfc-шная процедура находит у объекта CWnd функцию OnPaint и OnEraseBkgnd и вызывает их).
Причём часть перерисовки (как правило, заливку фона) — в WM_ERASEBKGND, а другую часть (содержательную) — в WM_PAINT.
Но у каждого окна свои представления о том, что содержательно, а что нет. (Например, STATIC — по моим наблюдениям — всё делает в WM_ERASEBKGND, а EDITBOX, напротив, в WM_PAINT).
Чтобы спровоцировать перерисовку, надо инвалидировать окно (всё целиком или его часть — ::InvalidateRect, ::InvalidateRgn, CWnd::Invalidate).
Здравствуйте, febus, Вы писали:
SM>>>Обработать сообщение WM_ERASEBKGND — в нем можно залить фон каким либо цветом, или даже вывести картинку.
IRI>>Можно уточнить, каким образом?
F>Примерно вот так: (сам не проверял, но вроде бы ок. Украдено здесь)
А как достать DC родительского окна, чтоб использовать его в OnEraseBkgnd?
Здравствуйте, IRINIC,
Мне сложно понять, чего именно ты пытаешься достичь. Думаю у остальных те же проблемы.
Чтобы внести в разговор немного конкретики, я сделал для тебя тестовый проект.
Он лежит здесь.
IRINIC, это то, что тебе нужно?
Основная работа по созданию прозрачного окна выполняется так:
Ко всем: Я пытался сделать прозрачными еще и MFC-окна видов, но у меня не получилось.
Проблема в том, что MFC не позволяет мне создавать CView с установленным стилем WS_EX_LAYERED.
С CChildFrame никаких проблем не возникло, а вот если с CView, то никак,- сообщение об неудачном создании окна.
Если кто захочет поэкспериментировать, уберите строчки
if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
{
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
}
из CBgndTestApp::InitInstance
Хотя конечно эта проблема к изначальной постановке вопроса отношения не имеет.