Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

MFC, рисование в CStatic через CDC

4.8K
16 июля 2004 года
Toc_vremenno
17 / / 02.04.2004
Здрасти. Такая беда.
Создал диалоговое окно. В него добавил элемент управления типа Bitmap, унаследовал его от класса CStatic, переопределил функцию OnPaint. Рядом с Bitmap разместил кнопку.
Теперь хочу по нажатии этой кнопки рисовать что-нибудь в этом Bitmap. Для этого создал функцию, которая рисует, вызываю её в OnPaint и OnButton1. Сделал, вроде рисует. НО. В debug версии постоянно выскакивают ASSERT после рисования. А в Release версии при завершении работы диалога - General Error.

Я делаю так (стилизовано).

void RePaint()
{
CDC *dc=GetDC();
dc->Rectangle(0,0,10,10);
}

void OnPaint()
{
RePaint();

}

void OnButton1()
{
RePaint();
}


Объясните, что за глюки? Чё я не так делаю?
4.8K
16 июля 2004 года
Toc_vremenno
17 / / 02.04.2004
Немножко подправил - Assert стал некритичным, то есть его можно пропустить, всё прорисовывается и продолжает работу. Но по окончании - всё равно General Error.

Я добавил ReleaseDC:

void RePaint()
{
CDC *dc=GetDC();
dc->Rectangle(0,0,10,10);

ReleaseDC(dc); // вот здесь изменение
}

Жду мнений
527
16 июля 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Toc_vremenno
Немножко подправил - Assert стал некритичным, то есть его можно пропустить, всё прорисовывается и продолжает работу. Но по окончании - всё равно General Error.

Я добавил ReleaseDC:

void RePaint()
{
CDC *dc=GetDC();
dc->Rectangle(0,0,10,10);

ReleaseDC(dc); // вот здесь изменение
}

Жду мнений


Не знаю поможет ли, но поправить стоит:
void Repaint(CDC *pdc)
{
dc->Rectangle(...);
}
void OnPaint()
{
CPaintDC dc(this);
Repaint(&dc);
}

void OnButton()
{
CDC *pdc = GetDC();
Repaint(pdc);
ReleaseDC(pdc);
}

492
19 июля 2004 года
alibabaich
238 / / 08.07.2004
Цитата:
Originally posted by pavor

Не знаю поможет ли, но поправить стоит:
void Repaint(CDC *pdc)
{
dc->Rectangle(...);
}
void OnPaint()
{
CPaintDC dc(this);
Repaint(&dc);
}

void OnButton()
{
CDC *pdc = GetDC();
Repaint(pdc);
ReleaseDC(pdc);
}


Я бы всё-таки создание контекста устройства и его удаление. Доверил бы конструктору и деструктору, соответственно. Во первых можно создать единожды, а во вторых не беспокоится о коректном удалении (Его уничтожит деструктор при выходе за пределы видимости).
Что то типа...
конструктор(...)
{
/*CDC*/ *m_dc=NULL
}
`деструктор
{
if(m_dc!=NULL)dc.Release();
}
Инициализация класса
{
dc = GetDC();
}

6.0K
19 июля 2004 года
Toyo
20 / / 03.06.2004
Дай свой мэйл. Я сброшу тебе тест-проект, в котором я вставляю битмэп в окно диалога и в кнопку.
4.8K
19 июля 2004 года
Toc_vremenno
17 / / 02.04.2004
Ошибку, возникавшую в конце работы исправил. Она оказалась никак несвязана с графикой, но была очень странна. Я выделял динамически массив целых одной длины, а записывал туда гораздо больше. Всё записывалось и читалось успешно. А в конце программы - сбой. Первый раз такое вижу. Обычно, если залезаешь за пределы массива - тут же получаешь error, а не в конце.

2 pavor

Переделал по твоему совету. Согласен, выглядит более корректно, но работает абсолютно так же. То есть, assert по-прежнему появляется, но не является критичным. Продолжаю поиски решения проблемы. Но чисто из интереса, потому что в сборке Release никаких Assert нет :) Всё работает отлично.

2 alibabaich

Дело в том, что я получаю контекст как раз между конструктором и деструктором. И не один раз. То, что ты описал, происходит и так на автомате. Проблема возникает в том случае, если я получаю из объекта его CDC *GetDC() и пытаюсь в нём рисовать. Сборка Debug тут же реагирует на такую попытку Assert'ом, но всё равно рисует. Мне не понятно такое поведение.

2 Toyo

Мой мэйл [email]tos@sinn.ru[/email], высылай.
6.3K
19 июля 2004 года
Сергей К.
14 / / 13.04.2004
Вот прям из программы кусок

void CPPGraphics::OnPaint()
{
CPaintDC dc( this );
CPaintDC DC( GetDlgItem( IDC_ST_SAMPLE ) );

DC.FillSolidRect( &m_rcClt, crBackGround );

int X0 = m_rcClt.left + 4,
X1 = m_rcClt.right - 4, Y;

for ( int i = 0; i < 8; i++ )
{
LOGBRUSH lbBrh = { BS_SOLID, m_dwLevCol, 0 };
CPen Pen( PS_GEOMETRIC | PS_ENDCAP_FLAT, m_dwWidC, &lbBrh, 0, NULL ),
*pPenOld = DC.SelectObject( &Pen );

Y = (i+1) * m_rcClt.Height() / 9;
DC.MoveTo( X0, Y ); DC.LineTo( X1, Y );
DC.SelectObject( pPenOld );
}
}

только я работаю напрямую со статиком (IDC_ST_SAMPLE) -- не делаю нового класса. посмотри может что подскажет.
492
19 июля 2004 года
alibabaich
238 / / 08.07.2004
Цитата:
2 alibabaich

Дело в том, что я получаю контекст как раз между конструктором и деструктором. И не один раз. То, что ты описал, происходит и так на автомате. Проблема возникает в том случае, если я получаю из объекта его CDC *GetDC() и пытаюсь в нём рисовать. Сборка Debug тут же реагирует на такую попытку Assert'ом, но всё равно рисует. Мне не понятно такое поведение.

2 Toyo

Мой мэйл [email]tos@sinn.ru[/email], высылай.


Release освобождает память если на объект больше нет ни одной ссылки. А Инициализация(присваевание Указателю адреса контекста устройства) происходи как раз между(InitDialog()). Я в статику объект DirectX выводил тем же образом. Может и путаю сейчас чего.

Ты создаёшь кажется ссылку но не присваеваешь ей адрес объекта. А так как Контекст у тебя один, Зачем его столько раз создавать. Тем более Если он и так уже есть... Тебе лишь требуется на него сослаться...

6.0K
19 июля 2004 года
Toyo
20 / / 03.06.2004
Цитата:
2 Toyo
Мой мэйл [email]tos@sinn.ru[/email], высылай.


Выслал. Если будут вопросы - пиши

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог