pOldFocus = pOldWnd;
}
void CFlatButton::OnLButtonUp(UINT nFlags, CPoint point) {
CButton::OnLButtonUp(nFlags, point);
CRect rectBtn;
GetClientRect(rectBtn);
if (rectBtn.PtInRect(point) && GetCapture() != this) {
bMouseCaptured = TRUE;
SetCapture();
Invalidate(FALSE);
}
SetOldFocus();
}
void CFlatButton::OnMouseMove(UINT nFlags, CPoint point) {
CRect rectBtn;
GetClientRect(rectBtn);
if (rectBtn.PtInRect(point)) {
BOOL bNeedUpdate =FALSE;
if (!bMouseCaptured) bNeedUpdate = TRUE;
bMouseCaptured = TRUE;
SetCapture();
if (bNeedUpdate) Invalidate(FALSE);
} else {
bMouseCaptured = FALSE;
ReleaseCapture();
SetOldFocus();
Invalidate(FALSE);
}
CButton::OnMouseMove(nFlags, point);
}
И, самое интересное… :-))) Перекрываем виртуальный метод:
void CFlatButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) {
// Test WS_TABSTOP
ASSERT(!(GetStyle() & WS_TABSTOP));
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CRect rectAll;
GetClientRect(rectAll);
CString text;
GetWindowText(text);
int save = pDC->SaveDC();
CRect rectText(rectAll);
rectText.DeflateRect(2,2);
CBrush bkBr(GetSysColor(COLOR_3DFACE));
pDC->FillRect(rectAll,&bkBr);
UINT state = lpDIS->itemState;
if (state & ODS_SELECTED) {
// Нажатое состояние
rectText.OffsetRect(1,1);
pDC->DrawEdge(rectAll, BDR_SUNKENOUTER, BF_RECT);
} else {
if (bMouseCaptured) {
pDC->DrawEdge(rectAll, BDR_RAISEDINNER, BF_RECT);
}
}
pDC->DrawText(text, rectText, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_TOP);
pDC->RestoreDC(save);
}
Использование: очень просто. Ставим на шаблоне диалога кнопку, убираем стиль WS_TABSTOP, ставим стиль WS_OWNERDRAW. В ClassWizard'е сопоставляем ей переменную типа CButton, затем тип переменной вручную меняем на CFlatButton. И всё. Далее – как с обычной кнопкой. У меня (VC++ 5.0) – работает.
Дмитрий Сулима
В ПОИСКАХ ИСТИНЫ
Q. Как включать в проект незарегистрированный компонент ActiveX? Вернее он на моей машине зарегистрирован, а на другой нет, и в результате этого программа на той машине вообще не запускается.
Сергей Лобачев
Это все на сегодня. Удачи вам!
Алекс Jenter jenter@mail.ru Красноярск, 2000.
Программирование на Visual C++
Выпуск №30 от 28 января 2001 г.
Здравствуйте, дорогие друзья!
Я очень рад вас всех вновь приветствовать! К сожалению, по не зависящим от меня причинам я не имел возможности выпускать рассылку вплоть до настоящего времени. Искренне прошу извинить за причиненные неудобства и такой вот вынужденный перерыв. Хочу развеять опасения некоторых товарищей: рассылку я закрывать не собираюсь. Начиная с сегодняшнего дня, выпуски будут опять выходить регулярно.
За это время количество подписчиков перевалило за 10 000 – действительно круглое число! Создавая рассылку, я и не предполагал, что она будет пользоваться такой популярностью – все-таки весьма специфичная тематика. Но это значит, что рассылка актуальна, и это не может не радовать. Что еще могу сказать – оставайтесь с нами, и скорее всего не пожалеете!
А теперь – let's get started!
СТАТЬЯ
Помнится, в одном из декабрьских выпусков шел у нас разговор о предотвращении запуска второй копии приложения. Тогда мы затронули тему использования объектов синхронизации, подробнее про которые я пообещал рассказать во второй части статьи про многозадачность. Тема эта хотя и очень интересная, но и довольно обширная; так что учитывая ограниченность места в одном выпуске, я освещу только самые важные для понимания моменты. Некоторые же второстепенные темы – такие, как предотвращение взаимного блокирования потоков, или оповещения об изменениях, – я здесь лишь упомяну, и (возможно) вынесу в дальнейшем в отдельную статью. Также в отдельную статью скорее всего выльется очень важная тема межпроцессного обмена данными (inter-process communication, IPC). Как скоро появятся эти статьи, будет зависеть от степени их востребованности. А пока представляю вашему вниманию давно обещанную вторую часть статьи про многозадачность.
Многозадачность и ее применение
Часть 2: Синхронизация потоков
Итак, в первой части статьи (см. №23) мы определили, что использование многопоточности находит себе широчайшее применение в самых различных программах и позволяет значительно повысить производительность и надежность приложений и системы в целом, сделать работу пользователя более комфортной, а также несколько упростить логику программы, производя естественное разделение обязанностей между потоками. Настоящий программист под Windows должен знать и уметь использовать преимущества операционной системы, одним из которых как раз и является вытесняющая многозадачность.
Читать дальше