- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
#import <craxdrt.tlb> no_namespace
#import <msado15.dll> rename("EOF", "adoEOF")
(подразумевается, что файл craxdrt.tlb находится в одной из стандартных папок для include. Изначально он находится в каталоге C:Program FilesSeagate SoftwareCrystal ReportsDeveloper Filesinclude)
так же добавляем следующие строки в начале файла RepSampDlg.cpp
const CLSID CLSID_Application = {0xb4741fd0, 0x45a6, 0x11d1, {0xab, 0xec, 0x00, 0xa0, 0xc9, 0x27, 0x4b, 0x91}};
const IID IID_IApplication = {0x0bac5cf2, 0x44c9, 0x11d1, 0xab, 0xec, 0x00, 0xa0, 0xc9, 0x27, 0x4b, 0x91}};
const CLSID CLSID_ReportObjects = {0xb4741e60, 0x45a6, 0x11d1, 0xab, 0xec, 0x00, 0xa0, 0xc9, 0x27, 0x4b, 0x91}};
const IID IID_IReportObjects = {0x0bac59b2, 0x44c9, 0x11d1, 0xab, 0xec, 0x00, 0xa0, 0xc9, 0x27, 0x4b, 0x91}};
Переходим к обработчику CRepSampDlg::OnShowWindow. Я обычно создаю стандартное окружение для работы с COM-объектами:
try {} catch(const _com_error& e) {
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
CString strError;
strError.Format("_com_error catched at CRepSampDlg::OnShowWindown"
"Source : %snDescription : %s", (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
AfxMessageBox(strError);
}
В try-блоке присоединяем наш файл отчета:
HRESULT hr=S_OK;
IApplicationPtr pApp;
IReportPtr pRep;
hr = CoCreateInstance(CLSID_Application, NULL, CLSCTX_INPROC_SERVER, IID_IApplication,
(void **)&pApp);
if (FAILED(hr)) _com_issue_error(hr);
pRep = pApp->OpenReport(_bstr_t("d:\projects\RepSamp\Report1.rpt"));
m_CRView1.SetReportSource(pRep);
m_CRView1.ViewReport();
Собираем проект, и запускаем. Появится отчет, который в качестве источника данных использует свои настройки по умолчанию. Теперь давайте подставим ему в качестве источника данных необходимый нам Recordset. Я предпочитаю ADO. Следующий код я добавил сразу после строки "HRESULT hr=S_OK;" :
ADODB::_ConnectionPtr pConn;
pConn.CreateInstance(__uuidof(ADODB::Connection));
if (FAILED(hr)) _com_issue_error(hr);
CString sConnStr("Provider=SQLOLEDB.1;"
"Integrated Security=SSPI;Persist Security Info= False;"
"Initial Catalog= pubs;Data Source= DATACENTER");
hr = pConn->Open(_bstr_t(sConnStr), _bstr_t(L""), _bstr_t(L""),
ADODB::adConnectUnspecified);
if(FAILED(hr)) _com_issue_error(hr);
ADODB::_RecordsetPtr pRs;
pRs.CreateInstance(__uuidof(ADODB::Recordset));
CString sSQL("SELECT * FROM authors");
pRs->Open(_bstr_t(sSQL), pConn.GetInterfacePtr(), ADODB::adOpenDynamic,
ADODB::adLockOptimistic, ADODB::adCmdText);
if (FAILED(hr)) _com_issue_error(hr);
теперь запихиваем наш recordset в отчет:
IApplicationPtr pApp;
IReportPtr pRep;
hr = CoCreateInstance(CLSID_Application, NULL, CLSCTX_INPROC_SERVER, IID_IApplication,
(void **) &pApp);
if (FAILED(hr)) _com_issue_error(hr);
pRep = pApp->OpenReport(_bstr_t("d:\proj\SampRep\Report1.rpt"));
m_CRView1.SetReportSource(pRep);
IDatabasePtr pDatabase = 0;
IDatabaseTablesPtr pTables = 0;
IDatabaseTablePtr pTable = 0;
pRep->get_Database((IDatabase**)&pDatabase);
pDatabase->get_Tables((IDatabaseTables**)&pTables);
VARIANT var, var2;
VariantInit(&var);
VariantInit(&var2);
var.vt = VT_DISPATCH;
var.pdispVal = (IDispatch*)pConn;
var2.vt = VT_DISPATCH;
var2.pdispVal = (IDispatch*)pRs->GetActiveCommand();
hr = pDatabase->AddADOCommand(var, var2);
ASSERT(SUCCEEDED(hr));
собираем проект. Всё готово.
ВОПРОС-ОТВЕТ Как сделать нестандартную кнопку на основе битмапа (без MFC, только WinAPI)? Автор: Игорь ВартановКнопка не обязательно должна иметь стандартный внешний вид (хотя лично я не нахожу внешний вид стандартной кнопки скучным или "простецким"). Однако для многих разработчиков и пользователей кнопки, имеющие нестандартный вид, выглядят более привлекательными. Поэтому для придания некоего стиля интерфейсу собственных программ можно использовать кнопки, отображающие некий битмап (bitmap – растровое изображение).
Кроме эффектов изображения можно использовать еще и эффекты формы – к примеру, круглая или овальная кнопка также достаточно оригинальны внешне, – но данная статья не рассматривает технику создания кнопок, имеющих форму, отличную от прямоугольной.
Windows имеет встроенные механизмы и API, поддерживающие создание кнопок (а также и других контролов), имеющих нестандартный внешний вид. Способ отрисовки внешнего вида контрола зависит от его стиля. В данном случае, стиль, нужный нам – это BS_OWNERDRAW. Из его названия видно, что отрисовку вида кнопки выполняет код пользователя, помещенный в оконную (диалоговую) функцию окна-владельца контрола.
Рассмотрим основные этапы отрисовки контрола, имеющего стиль xx_OWNERDRAW.
1. Родительскому окну контрола приходит сообщение WM_MEASUREITEM, в котором передается указатель на структуру MEASUREITEMSTRUCT через параметр lParam. Обработчик сообщения должен установить значения полей itemWidth и itemHeight структуры так, чтобы они содержали ширину и высоту контрола соответственно. Если мы обработали сообщение, обработчик должен вернуть значение TRUE из оконной процедуры. Это сообщение приходит владельцу один раз при создании контрола.
2. Каждый раз при необходимости перерисовать контрол его владельцу приходит сообщение WM_DRAWITEM. Параметр lParam сообщения содержит указатель на структуру DRAWITEMSTRUCT, подготовленную системой. В задачу данного сообщения входит предоставление контекста, в котором будет происходить отрисовка контрола. Хэндл контекста сопровождает дополнительная информация о внутреннем состоянии контрола, необходимая (возможно) для изменения его внешнего вида, а также информация о виде действия, производимого в настоящий момент с контролом. Далее мы увидим, каким образом эта информация может быть использована для изменения внешнего вида кнопки. И, опять-таки, если мы обрабатываем данное сообщение, обработчик обязан вернуть из оконной процедуры значение TRUE.
Поскольку мы реализуем, хотя и самостоятельно отрисовываемую, но все же кнопку, то было бы неплохо, если бы она имела поведение обычной кнопки – края кнопки в нормальном состоянии должны имитировать выпуклый контрол, при нажатом состоянии – вдавленный, при установленном фокусе кнопка должна иметь на себе прямоугольник, выполненный пунктирной линией, и в неактивном состоянии кнопка должна резко отличаться по цвету (либо фона, либо надписи, либо и того, и другого).
Выполняя указанные требования, мы можем подготовить четыре битмапа, реализующие внешний вид каждого из состояний кнопки, и отрисовывать в нужный момент (вот где появляется необходимость знать текущее состояние кнопки) одно из них. В этом случае мы сами полностью контролируем внешний вид кнопки в каждом из состояний. Впечатление, которое вы произведете на пользователя, будет целиком зависеть от вашего вкуса и умения создавать растровые изображения.
Что касается кода, реализующего необходимую логику работы, то его реализация может быть следующей:
BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
static HBITMAP hBm[BM_COUNT] = {NULL, NULL, NULL, NULL};
...
case WM_DRAWITEM:
return DrawFreeStyleBtn((LPDRAWITEMSTRUCT)lParam, hBm);
...
}
BOOL DrawFreeStyleBtn(LPDRAWITEMSTRUCT pis, HBITMAP* phBm) {
if (IDC_BMPBTN == pis->CtlID) {
HBITMAP hOld = NULL;
HBITMAP hbm = phBm[BM_UP];
switch(pis->itemAction) {
case ODA_DRAWENTIRE:
case ODA_SELECT:
if (pis->itemState & ODS_DISABLED) hbm = phBm[BM_DISABLE];
else if (pis->itemState & ODS_SELECTED) hbm = phBm[BM_DOWN];
break;
case ODA_FOCUS:
if (pis->hwndItem == GetFocus()) hbm = phBm[BM_FOCUS];
break;
}
HDC hCompDC = CreateCompatibleDC(pis->hDC);
hOld = (HBITMAP)SelectObject(hCompDC, hbm);
BitBlt(pis->hDC, pis->rcItem.left, pis->rcItem.top,
pis->rcItem.right - pis->rcItem.left, pis->rcItem.bottom - pis->rcItem.top,
hCompDC, 0, 0, SRCCOPY);
SelectObject(pis->hDC, hOld);
DeleteDC(hCompDC);
return TRUE;
}
return FALSE;
}
Как видим, ничего сложного. Код распадается на две части: в первой на основе сведений о выполняемых действиях (itemAction) и текущем состоянии кнопки (itemState) производится выбор необходимого битмапа, во второй части происходит вывод выбранного битмапа в контекст кнопки. Код обрамляется проверкой на необходимый идентификатор контрола, поскольку в рабочей программе подобных контролов может быть несколько.
Внимательный читатель готов задать вопрос о том, что в самом начале упоминались не только механизмы (реализованные, как мы выяснили, через сообщения WM_MEASUREITEM и WM_DRAWITEM), но и API?
Действительно, имеется несколько функций, облегчающих придание стандартного вида OWNERDRAW-контролам. Разработчик готовит только основной битмап для кнопки, а для отрисовки границ и состояний кнопки (неактивное и в фокусе) пользуется функциями WinAPI – DrawEdge() (границы контрола – "выпуклый/вдавленный"), DrawState() (состояние "активный/неактивный") и DrawFocusRect() (состояние "в фокусе"). В таком случае вышеприведенный код примет вид:
BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
static HBITMAP hBm = NULL;
...
case WM_DRAWITEM:
return DrawClassicStyleBtn((LPDRAWITEMSTRUCT)lParam, hBm);
...