Как реализовать диалог с фоновым изображением?

Автор: Сергей Пиманов
Опубликовано: 10.06.2001
Версия текста: 1.0

Демонстрационный проект BkDlg

Чтобы реализовать диалог с фоновым изображением, необходимо проделать следующие шаги.

Сначала добавляем член-переменные в класс диалога. Они понадобятся нам в дальнейшем.

CDC     m_dcTemp;
CBitmap m_cBmp;
UINT    m_iBmpHeight;
UINT    m_iBmpWidth;

Битмап, содержащий фоновое изображение, можно загружать как из файла, так и из ресурсов. Во втором случае необходимо добавить в ресурсы соответствующую картинку (например, с идентификатором IDB_BITMAP1).

Далее загружаем картинку в обработчике OnInitDialog(). Для случая с внешним файлом пишем:

m_hBmp=(HBITMAP)
LoadImage(0,"picture.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTSIZE);
m_cBmp.Attach(hBmp);

В случае с картинкой из ресурсов:

m_cBmp.LoadBitmap(IDB_BITMAP1);

Затем для обоих случаев:

BITMAP Bmp;
CClientDC dc(this);
m_dcTemp.CreateCompatibleDC(&dc); 
m_dcTemp.SelectObject(m_cBmp);
m_cBmp.GetBitmap(&Bmp);
m_iBmpHeight=Bmp.bmHeight;
m_iBmpWidth=Bmp.bmWidth;

Теперь создаём обработчик сообщения WM_ERASEBKGND, в котором наша картинка будет отрисовываться. Чтобы добавить этот обработчик с помощью ClassWizard, необходимо предварительно переключиться на вкладку Class Info и установить для класса диалога Message filter: Window.

BOOL CTestDlg::OnEraseBkgnd(CDC* pDC) 
{
    RECT rect;
    GetClientRect(&rect);

    int CX=rect.right/m_iBmpWidth;
    int CY=rect.bottom/m_iBmpHeight;

    int Y=0;
    for (int i=0;i<=CY;i++)
    {
        int X=0;
        for(int j=0;j<=CX;j++)
        {

            pDC->BitBlt(X,Y,X+m_iBmpWidth,Y+m_iBmpHeight,&m_dcTemp,0,0,SRCCOPY);
            X+=m_iBmpWidth;
        }

        Y+=m_iBmpHeight;
    }

    return TRUE;
}

Если битмап меньше окна, то он будет размножен (черепица). Возможно реализовать и другие варианты отображения картинки. Кроме черепицы, ещё два из них (центрирование и "растягивание" картинки по размеру окна) реализовано в демонстрационной программе BkDlg.

Вот и всё. Когда битмап больше не нужен, его следует удалить, но об этом за нас позаботится деструктор класса CBitmap.


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