Учебная работа. Курсовая работа: Розробка програми для демонстрації автомобільного руху через залізнодорожний переїзд
Вінницький національний технічний університет
Інститут інформаційних технологій та компьютер’ютерної інженерії
Кафедра захисту інформації
Розробка програми для
ДЕМОНСТРАЦІЇ АВТОМОБІЛЬНОГО РУХУ ЧЕРЕЗ ЗАЛІЗНОДОРОЖНІЙ ПЕРЕЇЗД
Вінниця 2008
Анотація
Даний курсовий проект призначений для демонстрування автомобільного руху через залізнодорожній переїзд . Програма демонструє рух автомобіля через переїзд, та наслідки, які можуть виникнути внаслідок неуважності працівника переїзду. Для досягнення поставленої задачі використовується програмне середовище Visual C++ 8.0 з використанням Win32 API функцій. Програма реалізує діалоговий інтерфейс користувача, який включає головне меню, що викликає потрібні користувачеві дії: пуск програми, виклик вікон для виконання потрібних дій.
ЗМІСТ
ВСТУП 5
1 Розробка структури програмного забезпечення
1.1 Обгрунтування структури програмного забезпечення
1.2 Розробка головного меню програми
1.3 Розробка структури програми
1.4 Створення ресурсів
1.5 метод роботи додатку
1.6 Розробка загальної схеми функціонування програми
2 Програмна реалізація задачі
2.1 Підбір програмних засобів
2.2 Реалізація інтерфейсу
2.3 Реалізація виведення графічних зображень
2.4 Програмна реалізація вікна
2.5 Програмна реалізація загальних елементів керування та музики
2.6 Програмна реалізація роботи з шлагбаумом
3 Аналіз результатів роботи програми
3.1 Інструкція з технічного обслуговування
3.2 Інструкція системного програміста
3.3 Інструкція програміста
3.4 Інструкція оператора
ВИСНОВКИ
ПЕРЕЛІК ВИКОРИСТАНИХ ДЖЕРЕЛ
Додаток. Лістинг програми
Вступ
Основною ідеєю структурного програмування є розділення складної задачі на декілька менших задач, і це ділення треба продовжувати до тих пір поки задачі не стануть простими для розуміння. Основною ідеєю сучасного програмування є створення окремих елементів, придатних до складання конкретних програм.
На відміну від бібліотек стандартних підпрограм, в яких теж використовується повторні модулі о’єктно-орієнтований підхід дозволяє створити ще ієрархію вкладених один в 1-го модулів. Модель о’єктно-орієнтованого програмування базується на декількох основних принципах: абстрагуванні даних, інкапсуляції, наслідувані та поліморфізмі.
Абстракція даних – це можливість визначати нові типи даних, з якими можна працювати майже так само, як і з основними. Такі типи називають абстрактними, хоча більш точною назвою є “типи даних, що визначаються користувачем”.
Інкапсуляція – це механізм, який о’єднує дані і код, що працює з цими даними і захищає перше та друге від зовнішнього втручання або неверного використання.
Наслідування – це процес, за допомогою якого один о’єкт може отримати властивості іншого.
Поліморфізм – це властивість програми вести для себя по-різному, в залежності від ситуації, що виникає в момент виконання. Ця властивість полягає у принципі перевантаження функцій, тобто в не однократній о’яві функції з різними типами аргументів. Всі вони базуються на використанні класів.
О’єктно-орієнтоване програмування є дуже потужним засобом програмування, який є одним з передових підходів до програмування. Однією з найдосконаліших програмних реалізацій цієї мови є програмний пакет Microsoft Visual C++ 8.0, за допомогою якого і буде реалізована дана курсова бота.
1 Розробка структури програмного забезпечення
1.1 Обґрунтування структури програмного забезпечення
Оскільки данна програма буде використовуватись в середовищі MS Windows, потрібно створити, просте та зручне для користувача, меню.
Для демонстрації автомобільного руху через переїзд необхідно використати зрозумілий інтерфейс та зробити зрозумілою боту самої програми. Меню буде створене з простими та зручними пт.
Меню має складатись з таковых пунктів: “Старт Поїзда”, “Керування Шлагбаумом”, “Сервіс”, “Вихід”. В пункті меню “Сервіс будуть: відомості про розробника програми, саме завдання та допомога по використанню програмного продукту.
Самим головним пт меню програми буде “Старт Поїзда”. Який наглядно покаже рух автомобіля (рух автомобіля керується за допомогою шлагбаума), поїзда, та приклад аварії.
1.2 Розробка головного меню програми
Меню повинно містити два основні та два додаткових розділи: Старт Поїзда та Керування шлагбаумом, Сервіс та Вихід, в яких буде реалізовано доступ користувача до всіх можливостей програмного продукту.
Розглянемо кожен пункт меню детальніше:
Старт поїзда – початок руху поїзда.
Керування Шлагбаумом:
— Підняти Шлагбаум;
— Опустити Шлагбаум;
Сервіс:
– Завдання Курсової – варіант та зміст задачі;
– Інфо –відомості про виконавця;
– Допомога – допомога.
Вихід – завершення роботи програми .
1.3 Розробка структури програми
Розглянемо структуру програми. Після запуску програми, на екрані з’явиться головне вікно додатку. У ньому буде реалізовано фоновий малюнок, на якому буде відбуватись власне й рух автомобіля та поїзда. Рух буде показаний у вигляді чотирьох малюнків, завантажених у проект (детальніше при програмній реалізації): дорога і переїзд (Background..bmp), шлагбаум (Shlagbaym.bmp), поїзд (train.bmp), автомобіль (car2.bmp).Для того, щоб програма була зручною для користувача, потрібно створити дружній і зручний інтерфейс. Це може бути свій оригінальний курсор, іконка, екранна заставка і т.п.
Клавиши Завдання Курсової, Інфо, Допомога будуть представленні у вигляді діалогових вікон.
Підсумовуючи вище сказане, можна зробити висновок, що майбутній програмний продукт буде складатися з однієї віконної та чотирьох діалогових процедур, що забезпечить створення зручного для стороннього користувача інтерфейсу.
1.4 Створення ресурсів
Для підключення іконки та курсору необхідно підключити до проекту створений файл ресурсів. Назвемо його l3.rc. Добавимо курсор: IDC_CURSOR1, (рис. 1.1), далі іконки: IDI_Icon1, IDI_ICON2 (рис. 1.2).
Набросок 1.1 – Вигляд курсору
Набросок 1.2 – Вигляд іконок
Для підключення ресурсів потрібно на початку програми написати таку стрічку: #include «resource.h», та вказати курсор, меню та іконку при реєстрації вікна:
RegClass(WndProc,szMainClass,COLOR_APPWORKSPACE,IDI_Icon1,IDC_CURSOR1,
IDR_MENU1)
Завдання курсової (рис. 1.3), інформація про виконавця (рис. 1.4), допомога (рис. 1.5) потрібно оформити діалоговими вікнами, щоб зробити стиль програми більш гарнішимзручнішим.
Набросок 1.3 – Вигляд діалогового вікна «Завдання Курсової роботи»
Набросок 1.4 – Вигляд діалогового вікна «Інфо»
Набросок 1.5 — Вигляд діалогового вікна «Допомога»
1.5 метод роботи додатку
При натисненні на пункт меню «Старт Поїзда» буде рухатись поїзд, при цьому машинка рухається залежно від положення шлагбауму. При натисненні на «Керування Шлагбаумом» ->«Підняти Шлагбаум» - шлагбаум піднімається, і автомобіль продовжує рух, «Керування Шлагбаумом» ->«Опустити Шлагбаум» - шлагбаум опускається і автомобіль зупиниться, если під`їде до нього. Нижче наведено метод, за яким працює додаток (рис. 1.6).
Набросок 1.6 – метод дорожнього руху
1.6 Розробка загальної схеми функціонування програми
При завантаженні програми відкриється вікно з меню. метод, представлений у вигляді схеми, наведений нижче (рис. 1.7).
Набросок 1.7 – Загальна схема програми
2 Програмна реалізація задачі
2.1 Підбір програмних засобів
В даному програмному продукті потрібно наглядно показати, як підключити і працювати з ресурсами при використанні API-функцій. Програма складається з однієї віконної та чотирьох діалогових функцій, що викликаються в залежності від установок користувача. Для дерматологического вікна потрібно реалізувати прийнятний для користувача інтерфейс. Для цього потрібно показати як реалізується графічне представлення програми, як потрібно створити і працювати з різними типами вікон.
Для більш цікавішої роботи програми потрібно підключити загальні елементи керування та доповнити рух певними звуками. Рухомість графічних зображень додасть програмі динамічності.
Реалізацію дерматологического елемента програми розглянемо в окремих пт.
2.2 Реалізація інтерфейсу
Як було сказано у попередніх розділах головне меню знаходиться в головному вікні. Воно складається з розділів: Старт Поїзда, Керування Шлагбаумом, Сервіс та Вихід. При натисненні на «Вихід» вилетить текстове повідомлення, яке буде просити відповіді. Це повідомлення являє собою функцію MessageBox, яка створює, відображає, забезпечує боту та закриває вікно повідомлення:
int WIAPI MessageBox(HWND hWnd, LPCTSTR Text, LPCTSTR lpCaption,
UINT uType );
Якщо hWnd=NULL, вікно повідомлення не має батьківського вікна. При lpCaption = NULL, в заголовок виводиться рядок “Помилка”. Параметр uType визначає зміст та поводження вікна повідомлень. Також передбачена можливість видачі звукових повідомлень, при визові функції MessageBeep. Синтаксис цієї функції:
BOOL MessageBeep(UINT uType);
У даній курсовій роботі MessageBox використовується при виході із програми в такому вигляді:
MessageBox(hWnd,
«Вивпевнені?»,
«?»,
MB_OKCANCEL|MB_ICONQUESTION|MB_SYSTEMMODAL);
Інші пт меню розглянемо під наступними розділами.
2.3 Реалізація виведення графічних зображень
Даний програмний продукт має доволі багато графічної інформації, що на думку виконавця повинно надавати програмі кращого вигляду.
Виведення графічної інформації відбувається при обробці повідомлення системи WM_Paint за допомогою о’єкту типу HDC, за допомогою функції BeginPaint().
Так в головному вікні виводиться фоновий малюнок, значок університету та текст. Малюнок та значок являють собою растрові зображення, для їх виводу використовують тип BITMAP. Ці о’єкти потрібно загрузити з файлу в пам’ять, визначити розміри вікна і розташувати по своїм місцям у вікні.
Програмний код, що реалізує виведення фонового малюнку представлений нижче.
PAINTSTRUCT ps; // структура для параметрів контексту
hdc = BeginPaint(hWnd, &ps); // отримуємо хендл контексту пристрою
hBmpBckGrnd = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
GetObject ( hBmpBckGrnd, sizeof(BITMAP),&bitmap);// отрималирозміризображення
hCompDC = CreateCompatibleDC ( hdc );
oBitmap = (HBITMAP)SelectObject ( hCompDC, hBmpBckGrnd );
// ввели наше зображення у контекст в пам’яті
// і запам’ятали те, що витіснили звідти
StretchBlt (hdc, r.left, r.top, r.right, r.bottom, // куди
hCompDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, // звідки
SRCCOPY); // як
// “натягнули” зображення в пам’яті на екран
SelectObject ( hCompDC, oBitmap ); // повернули в контекст в пам’яті попередній //вміст
DeleteObject ( hBmpBckGrnd ); // знищили о’єкт
2.4 Програмна реалізація вікна
Вікно повинне мати свою віконну функцію:
hWnd = CreateWindow (szMainClass,// Створюється вікно нашого класу
szTitle, // Заголовок створюємого вікна
WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX|
WS_VISIBLE|WS_BORDER|WS_DLGFRAME|
TBSTYLE_TOOLTIPS, //Тип вікна
CW_USEDEFAULT, //стандартне
//гориз. разміщення
CW_USEDEFAULT, // обычное
//вертикальне розміщення
1000, //обычна ширина вікна
600, // обычна висота вікна
NULL, // дескриптор батьківського вікна
NULL, // меню у вікна відсутнє
hInstance, // дескриптор программки */
NULL // покажчик на данні вікна(для MDI-вікон));
if (!hWnd) return NULL;
Дерматологического разу вікно потрібно показати та обновити у пам’яті:
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
Щоб зареєструвати вікно потрібно використати API-функцію RegisterClass(&wc).
if(!RegClass(WndProc,szMainClass,COLOR_APPWORKSPACE,IDI_Icon1,IDC_CURSOR1,IDR_MENU1)) return FALSE;
Для створення діалогового вікна потрібна наявність трьох компонентів:
– шаблону діалогу (описує форму і розміщення самого діал. вікна і всіх його внутрішніх елементів керування на екрані);
– програмного коду, який утворює і відображає його на екрані;
– діалогової процедури, яка обслуговує взаємодію користувача з блоком діалогу.
Діалогова процедура потрібна для обробки повідомлень, пов’язаних з обміном даних у діалоговому вікні.
Для дочірніх та діалогових вікон потрібно о’явити макет віконної функції:
BOOL CALLBACK DlgProg(HWND hdWnd,UINT mes,WPARAM wParam,LPARAM lParam);
BOOL CALLBACK DlgProg2 (HWND hdWnd,UINT mes,WPARAM wParam,LPARAM lParam);
BOOL CALLBACK DlgProg3 (HWND hdWnd,UINT mes,WPARAM wParam,LPARAM lParam);
BOOL CALLBACK DlgProg4 (HWND hdWnd,UINT mes,WPARAM wParam,LPARAM lParam);
Програмна реалізація діалогового вікна, що містить завдання:
BOOL CALLBACK DlgProg2(HWND hdWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
{
EndDialog(hdWnd, 0);
return 1;
}
}
return 0;
}
2.5 Програмна реалізація загальних елементів керування та музики
Для того, щоб показати свої вміння більш широкого використання ресурсів мови програмування VС++, я використав два загальних елементи керування: Стрічки стану та акселератори.
Щоб додати до проекту будь – який елемент керування потрібно зробити такі додаткові дії:
– #include <commctrl.h>
– Project Setting Link ObjectLibrary modules : comctl32.lib
Підключаємо до проекту бібліотеку <commctrl.h>, яка містить бази даних для роботи з загальними елементами керування та дописуємо по вище написаному напрямку рядок comctl32.lib.
Добавлення рядка стану має такий вигляд:
#define ID_STATUS 120
…
LRESULT CALLBACK Window (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static HWND hStatus;
switch(msg)
{
case WM_CREATE:
WS_VISIBLE,
«Готово», hWnd, ID_STATUS);
return 0;
…
}
Рядок стану – це дочірнє вікно з певними параметрами. Для того, щоб розбити цей рядок на декілька областей потрібно:
static int parts[2];
…
parts[0]=cx/2; parts[1]=cx;
SendMessage(hStatus,SB_SETPARTS,2,(LPARAM)parts);
…
Для підключення акселераторів ( комбінація клавіш ) потрібно:
– Insert Resource Accelerator
– Описати потрібний набір клавіш для пунктів меню
Або в самій програмі потрібно написати:
HACCEL CreateAccelTable(void)
FCONTROL;
Accel[0].key=0x53;//»S»
Accel[0].cmd=IDM_START;
//Шлагбаум
Accel[1].fVirt=FVIRTKEY
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
HACCEL hAccel=CreateAccelTable();
}
…
while(GetMessage(&msg,NULL,0,0))
{
if (!TranslateAccelerator(hWnd,hAccel,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DestroyAcceleratorTable(hAccel);
…
Для додання до проекту звуку потрібно зробити такі додаткові дії:
– Project Setting Link ObjectLibrary modules : winmm.lib
Для того, щоб грав звук потрібно написати таку функцію:
PlaySound (“train”, hInstance, SND_RESOURCE | SND_ASYNC)
Перший параметр відповідає за назву звуку.
2.6 Програмна реалізація роботи з шлагбаумом
Спочатку необхідно о’явити змінні, які будуть відповідати за рух машини та поїзда. Оскільки цих два о’єкти являють собою малюнки їх необхідно завантажити у ресурси, а потім завантажувати з ресурсів у програму.
Програмна реалізація зображення машини:
hBmpCar1 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP4));
DrawTransparentBitmap(hdc, // кінцевий DC.
hBmpCar1, // Бітмап, який буде намальований
X2, // координата X.
Y2, // координата Y.
0x00FFFFFF); // Колір для прозорих
// пикселів (в данном випадку білий
DeleteObject ( hBmpCar1 ); // знищили о’єкт
Програмна реалізація зображення поїзда:
hBmpTrain = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP4));
DrawTransparentBitmap(hdc, // кінцевий DC.
hBmpTrain, // Бітмап, якийбуденамальований
X, // координата X.
Y, // координата Y.
0x00FFFFFF); // Колір для прозорих
// пикселів (в данном випадку білий
DeleteObject (hBmpTrain ); // знищили о’єкт
Для того, щоб машинка та поїзд рухались необхідно змінювати значення змінних X2 та Y2 – для машини, X – для поїзда (оскільки поїзд рухається горизонтально, координата Y залишається сталою), які відповідають за поточне місце на фоні . Над цією задачею працює таймер:
caseWM_TIMER:
{
if ((shlagbaym==0)||(Y2<330)||(Y2>350))
{
if (car==0)
{
Y2-=13;
InvalidateRect(hWnd, &car1, FALSE);
}
if (car==1)
{
if (wham==0)
SND_ASYNC);
wham++;
X2+=13;
InvalidateRect(hWnd, &car1, FALSE);
}
if ((Y2<-200)||(X2>1000))
{
Y2=800;
X2=450;
}
}
if (par==1)
{
X+=10;
InvalidateRect(hWnd, &train, FALSE);
if(X<=(X2+45)&&(X+538)>=(X2-1)
&&(Y+118)>=(Y2+1)&&(Y<=Y2+85))
car=1;
if (X>1001)
{
X2=450;
par=0;
car=0;
wham=0;
}
}
return 0;
}
Для запуску таймера необхідно записати таку функцію:
int Speed=10;
…………….
SetTimer(hWnd,1,Speed,NULL);
Перший параметр вказує дескриптор вікна, другий – номер таймера, третій – швидкість. Останній пов’язаний з системою, за замовчуванням рівний нулю.
Шлагбаум теж потрібно намалювати:
if(shlagbaym==0)
{
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)»Увага!
Шлагбаумвідкрито!»);
if (w==0)
{
InvalidateRect(hWnd, &shlagbm, FALSE);
w++;
}
hBmpShlagbaym = LoadBitmap(hInstance,
MAKEINTRESOURCE(IDB_BITMAP9));
DrawTransparentBitmap(hdc,hBmpShlagbaym,X3,Y3,0x00FFFFFF);
DeleteObject ( hBmpShlagbaym ); // знищилиоб’єкт
}
if(shlagbaym==1)
{
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)»Увага! Шлагбаум
закрито!»);
if (w==1)
{
InvalidateRect(hWnd, &shlagbm, FALSE);
w—;
}
hBmpShlagbaym = LoadBitmap(hInstance,
MAKEINTRESOURCE(IDB_BITMAP5));
DrawTransparentBitmap(hdc,hBmpShlagbaym,X3,Y3,0x00FFFFFF);
DeleteObject ( hBmpShlagbaym );
}
В залежності від змінної shlagbaym , шлагбаум знаходить або в опущеному або у піднятому стані.
При натисненні на «Керування Шлагбаумом» ->«Підняти Шлагбаум» шлагбаум піднімається, і автомобіль продовжує рух, «Керування Шлагбаумом» ->«Опустити Шлагбаум» шлагбаум опускається і автомобіль зупиниться, если під`їде до нього. Щоб уникнути ДТП — событие, возникшее в процессе движения по дороге транспортного средства и с его участием, при котором погибли или пострадали люди, повреждены транспортные средства, сооружения, грузы, либо причинён иной материальный ущерб) потрібно вчасно закрити шлагбаум, якщо не встигли – далі все залежить від випадку. Фрагмент коду, що описує все це наведемо нижче:
{
if ((shlagbaym==0)||(Y2<330)||(Y2>350))
{
if (car==0)
{
Y2-=13;
InvalidateRect(hWnd, &car1, FALSE);
}
if (car==1)
{
if (wham==0)
SND_ASYNC);
wham++;
X2+=13;
InvalidateRect(hWnd, &car1, FALSE);
}
if ((Y2<-200)||(X2>1000))
{
Y2=800; //Збиваємо значення на початкові
X2=450;
}
}
if (par==1)
{
X+=10;
InvalidateRect(hWnd, &train, FALSE);
if(X<=(X2+45)&&(X+538)>=(X2-1)&&(Y+118)>=(Y2+1)&&(Y<=Y2+85))
car=1;
if (X>1001)
{
X2=450; //Збиваємо значення на початкові
par=0;
car=0;
wham=0;
}
}
return 0;
}
3 Аналіз результатів роботи програми
Програмний продукт _-=Мій Курсовий Проект=-_ наглядно показує регулювання автомобільного руху через залізнодорожній переїзд, при використанні шлагбауму. Розроблений програмний продукт необхідно перевірити на конкретність роботи і підготувати інструкцію по роботі з ним.
3.1 Інструкція з технічного обслуговування
Вступ.
Дана інструкція призначена для технічного обслуговування програми, тобто встановлення її на компьютер’ютер та експлуатації.
Загальні вказівки.
Програма встановлюється на компьютер’ютер який відповідає вимогам технічних засобів поданих нижче.
Вимоги до технічних засобів.
Мінімальні системні вимоги:
– Pentium III 1.5ГГц;
– 128 MБ RAM;
– 12 MБ вільного місця на жорсткому диску;
– Вмонтована звукова карта;
– Windows ME, XP.
Рекомендовані системні вимоги:
– Pentium III 2.0 ГГц;
– 128 MБ RAM;
– 15 MБ вільного місця на жорсткому диску;
– Вмонтована звукова карта;
– Windows МЕабо XP.
Опис функцій.
Основне призначення програми _-=Мій Курсовий Проект=-_ наглядно показати регулювання автомобільного руху через залізнодорожній переїзд, при використанні шлагбауму. Для перевірки працездатності програми потрібно скористатись інструкцією системного програміста.
3.2 Інструкція системного програміста
Загальні відомості про програму.
Основне призначення програми _-=Мій Курсовий Проект=-_ наглядно показати регулювання автомобільного руху через залізнодорожній переїзд, при використанні шлагбауму.
структура програми.
Для початку роботи необхідно дану програму скопіювати на компьютер’ютер в окрему папку. Сама програма складається 1-го файлу (рис. 3.1):
– My_Kursach.exe – завантажувальний файл програми.
Набросок 3.1 – Вигляд компонентів програми
Програма використовує 8024 Кбайт оперативної пам’яті.
Займає 5 885 952 б пам’яті на жорсткому диску.
Перевірка програми.
Для того, щоб перевірити правильність роботи шлагбауму по регулюванню дорожнього руху потрібно виконати таку послідовність дій:
1. Виконати таку послідовність дій «Керування Шлагбаумом» ->«Опустити Шлагбаум»
2. Натиснути лівою кнопкою миші на пункт меню “Старт поїзда”
3. ДТП — событие, возникшее в процессе движения по дороге транспортного средства и с его участием, при котором погибли или пострадали люди, повреждены транспортные средства, сооружения, грузы, либо причинён иной материальный ущерб) не повинне виникнути.
4. Виконати таку послідовність дій «Керування Шлагбаумом» ->«Підняти Шлагбаум»
5. Натиснути лівою кнопкою миші на пункт меню “Старт поїзда”
6. ДТП — событие, возникшее в процессе движения по дороге транспортного средства и с его участием, при котором погибли или пострадали люди, повреждены транспортные средства, сооружения, грузы, либо причинён иной материальный ущерб) повинне виникнути в залежності від випадку, якщо ж таки автомобілю «повезе» проскочити перед поїздом, тоді пункт №5 повторити ще раз.
Якщо під час виконання усіх 6 пунктів все пройшло так як пояснювалось у пункті №3 (ДТП — событие, возникшее в процессе движения по дороге транспортного средства и с его участием, при котором погибли или пострадали люди, повреждены транспортные средства, сооружения, грузы, либо причинён иной материальный ущерб) не відбулось, хіба що шлагбаум був закритий запізно) і №6 (ДТП — событие, возникшее в процессе движения по дороге транспортного средства и с его участием, при котором погибли или пострадали люди, повреждены транспортные средства, сооружения, грузы, либо причинён иной материальный ущерб) відбулось, при відкритому шлагбаумі) – програма верно виконує свою боту.
3.3 Інструкція програміста
Призначення і умови застосування програми.
Основне призначення програми _-=Мій Курсовий Проект=-_ наглядно показати регулювання автомобільного руху через залізнодорожній переїзд, при використанні шлагбауму.
Програма використовує 8024 Кбайт оперативної пам’яті.
Займає 5 885 952 б пам’яті на жорсткому диску.
Черта програми.
Режим роботи визначається пт меню. (детальніше в інструкціях оператора). При наявності помилок в роботі шлагбауму закрити вікно додатку і перезавантажити програму. Якщо помилка не виправилась потрібно переустановити програмний продукт.
Звернення до програми.
Повний лістинг програми наведений в додатку. Бота окремих модулів наведена в другому розділі. Для внесення будь-яких в роботі програми необхідно відкоригувати потрібний код програми та виконати компіляцію.
3.4 Інструкція оператора
Призначення програми.
Основне призначення програми _-=Мій Курсовий Проект=-_ наглядно показати регулювання автомобільного руху через залізнодорожній переїзд, при використанні шлагбауму.
Умови виконання програми.
Програма буде працювати при складі апаратних і програмних засобів, які вказані в інструкціях з технічного обслуговування.
Виконання програми.
Для правильного функціонування даного програмного продукту ці файли повинні міститись в одній папці, бажано окремій (рис. 3.2):
Набросок 3.2 – Вигляд
Набросок 3.3 – Загальний вигляд вікна
Якщо ви звернете увагу на самий низ вікна, ви побачите стрічку стану. При появі вікна, у ньому зразу буде рухатись автомобіль (рис 3.4).
Набросок 3.4 – Загальний вигляд вікна з автомобілем
Натиснувши пункт меню «Старт поїзда» – почне рухатись поїзд(рис 3.5).
Набросок 3.5 – Загальний вигляд вікна з автомобілем та потягом
Завдяки курсору миші користувач може маніпулювати рухом автомобіля і запускати рух поїзда. Керування автомобілем та пуск поїзда здійснюється завдяки натисканню лівої клавиши миші на пункті меню «Керування шлагбаумом» «Підняти шлагбаум» чи «Опустити шлагбаум», запустити потяг — «Старт поїзда», або за допомогою гарячих клавіш: Ctrl+W – Керування шлагбаумом, Ctrl+S – Старт поїзда (рис 3.6).
Набросок 3.6 – Керування шлагбаумом та Старт поїзда
Набросок 3.7 – Вигляд опущеного шлагбауму та поїзда в русі
Скориставшись меню Допомога (рис 3.8) отримаємо допомогу як керувати шлагбаумом та Запускати поїзд.
Набросок 3.8 – Вигляд діалогового вікна “Допомога”
Для отримання відомостей про розробника програми використовуємо клавішу – акселератор Ctrl+I – це є пункт меню Інфо (рис 3.9).
Набросок 3.9 – Вигляд діалогового вікна “Создатель”
Для отримання відомостей про завдання роботи використовуємо пункт меню «Сервіс» «Завдання Курсової» (рис 3.10).
Набросок 3.10 – Вигляд діалогового вікна “Завдання”
Для виходу з програми використовуємо «Вихід» або комбінацію клавіш Ctrl + E – для швидкого доступу до даного пт меню (рис 3.11).
Набросок 3.14 – Вигляд вікна повідомлення при виході з програми
При невірному виконанні роботи програми чи виникненні певних заморочек у користуванні звертатися до розробника програмного продукту.
Висновки
В даній курсовій роботі було розроблено та реалізовано за допомогою мови програмування VС++ програмний продукт для демонстрації регулювання автомобільного руху через залізнодорожній переїзд з використанням шлагбауму.
При програмній реалізації були використані всі основні принципи о’єктно-орієнтованого програмування, тобто абстракція, наслідування, поліморфізм та інкапсуляція, оскільки мова програмування VС++ базується саме на цих принципах. Значною перевагою мови програмування VС++ відносно мов програмування, заснованих на принципах структурного та процедурного програмування, є те, що вона дозволяє верно користуватись вже розробленими раніше функціями, о’єктами даних, не знаючи їх опису і о’яви. Це значно спрощує процес програмування і підвищує можливості даної мови. Так розробка ресурсів і використання стандартних панелей та елементів керування системи Windows в даній курсовій роботі відбувалося без знання, яким саме чином написані функції, які використовуються. Головне – це той итог, який повертає та чи інша функція.
Головним недоліком о’єктно-орієнтованого програмування є те, що неувязка реалізації рішення тієї чи іншої задачі, полягає у проблемі пошуку потрібної функції, та інформації щодо її використання. Але пошук даної функції може зайняти навіть більше часу, ніж написання її аналогу програмістом. Крім того через незнання елементарних функцій, таковых як АРІ-функції робить написання цього аналогу неможливим.
Отже мова програмування С++, як і інші мови, засновані на принципі о’єктно-орієнтованого програмування, не є досконалою, проте вона набагато більше відкрита для удосконалення, ніж мови, що засновані на інших принципах програмування. Тому вже сразу вона вважається найкращою для написання комерційних програм зі зручним інтерфейсом.
Перелік використаних джерел
1. Поляков А. Ю., Брусенцев В. А. способы и методы компьютерной графики в примерах на Visual C++, 2-е изд., перераб. и доп. – СПб.: БХВ-Петербург, 2003. – 560 с.
2. Либерти Джесс. Освой без помощи других С++ за 21 денек, 4-е издание. : Пер. с англ. – М. : Издательский дом «Вильямс», 2003. – 832 с.
3. Глушаков С. В., Коваль А. В., Черепкин С. А. Програмирование на Visual C++ 6.0, Харьков: Фолио, 2002. – 726 с.
4. Семеренко В. П. Програмування мовами С та С++ в середовищі Windows. Навчальний посібник. – Вінниці: УНІВЕРСУМ – Вінниця, 2003. – 128 с.
5. Холзнер С. Visual C++ 6.: Учебный курс-СПб.: Питер, 2001. – 576 с.
6. Ганеев. Р. М. Проектирование интерфейса юзера средствами Win32 API. .: Питер, 2001. – 350 с.
7. Конспект лекцій з дисципліни ,,Програмування’’ за перший та другий курси.
8. Павловская Т.А.. С/С++. Программирование на языке высочайшего уровня – СПб. : Питер, 2004. – 461 с.
9. Методичка.
Додаток
Лістинг програми
#include <windows.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <commctrl.h>
#include «resource.h»
#define ID_STATUS 200
/* Прототипыфункций */
BOOL RegClass(WNDPROC,LPCSTR,UINT,UINT,UINT,UINT);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProg(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProg2(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProg3(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DlgProg4(HWND, UINT, WPARAM, LPARAM);
HACCEL CreateAccelTable(void);
void DrawTransparentBitmap(HDC, HBITMAP, short,short, COLORREF);
HINSTANCE hInstance;
char szMainClass[]=»Головнийклас»;
char szTitle[]=»_-=Мій Курсовий Проект=-_»;
int X=-400, Y;
int X2=450, Y2=800;
int X3=460, Y3=120;
int Speed=50;
int par=0;
int car=0;
int shlagbaym=0, w=0;
int wham=0;
static TBBUTTON but[4];
HACCEL CreateAccelTable(void)
FCONTROL;
Accel[0].key=0x53;//»S»
Accel[0].cmd=IDM_START;
//Шлагбаум
Accel[1].fVirt=FVIRTKEY
int WINAPI WinMain (
HINSTANCE hInst,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
MSG msg; /* структура для хранения сообщений */
static HWND hWnd; /* Дескриптор окна */
BOOL bRet; // for return value of GetMessage
hInstance=hInst;
if(!RegClass(WndProc,szMainClass,COLOR_APPWORKSPACE,IDI_Icon1,IDC_CURSOR1,IDR_MENU1))
return FALSE;
hWnd = CreateWindow (
szMainClass, /* Создаетсяокнонашегокласса */
szTitle, /* Заголовоксоздаваемогоокна */
WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE|WS_BORDER|WS_DLGFRAME|
TBSTYLE_TOOLTIPS, /* Обычный тип окна */
CW_USEDEFAULT, // стандартн. горизонтальное размещение
CW_USEDEFAULT, // обычное вертикальное
1000, //обычная ширина окна
600, // обычная высота окна
NULL, // дескриптор родительского окна
NULL, // меню у окна отсутствует
hInstance, // дескриптор экземпляра программки */
NULL // указатель на данные окна (для MDI-окон)
);
if (!hWnd) return NULL;
but[0].iBitmap=STD_FILESAVE;
but[0].idCommand=IDM_START;
but[0].fsState=TBSTATE_ENABLED;
but[0].fsStyle=TBSTYLE_GROUP;
but[1].iBitmap=STD_CUT;
but[1].idCommand=IDM_EDIT;
but[1].fsState=TBSTATE_ENABLED;
but[1].fsStyle=TBSTYLE_BUTTON;
but[2].iBitmap=STD_COPY;
but[2].idCommand=IDM_INFO;
but[2].fsState=TBSTATE_ENABLED;
but[2].fsStyle=TBSTYLE_BUTTON;
but[3].iBitmap=STD_FILEOPEN;
but[3].idCommand=IDM_EXIT;
but[3].fsState=TBSTATE_ENABLED;
but[3].fsStyle=TBSTYLE_BUTTON;
CreateToolbarEx(hWnd,
WS_CHILD|WS_VISIBLE|WS_DLGFRAME|TBSTYLE_TOOLTIPS,
IDR_Toolbar1,
0,
HINST_COMMCTRL,
IDB_STD_SMALL_COLOR,
but,
4,
0,0,0,0,
sizeof(TBBUTTON));
ShowWindow(hWnd,nCmdShow); // функцiявiдображеннявiкна
UpdateWindow(hWnd); // функцiяоновленнявiкна
HACCEL hAccel=CreateAccelTable();
while ((GetMessage(&msg, NULL, 0, 0))!= 0)
{
if (!TranslateAccelerator( hWnd, // handle to receiving window
hAccel, // handle to active accelerator table
&msg)) // Message data
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
DestroyAcceleratorTable(hAccel);
return msg.wParam;
}
BOOL RegClass(WNDPROC Proc, LPCSTR szName,UINT brBackground,UINT ic,UINT cur,UINT menu)
CS_BYTEALIGNCLIENT;
wc.cbClsExtra=wc.cbWndExtra=0; /* стильокна */
wc.hInstance = hInstance; /* дескрипторэкземплярапрограммы */
wc.hIcon = LoadIcon( hInstance, (LPCSTR)ic );
wc.hCursor = LoadCursor( hInstance, (LPCSTR)cur );
wc.hbrBackground = (HBRUSH)(brBackground+1);
wc.lpszMenuName = (LPCSTR) menu;
return(RegisterClass(&wc)!=0); /* Регистрируемклассокна */
/* Оконнаяпроцедура */
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam )
{
HDC hCompDC, hdc; // хендликонтекстівпристрою
HBITMAP hBmpBckGrnd, hBmpTrain, oBitmap, hBmpCar1, hBmpShlagbaym;
// хендлинашогозображенняістарого
BITMAP bitmap; // длязберіганнярозмірівзображення
RECT r; // длязберіганнярозмірівекрану
RECT train, car1, shlagbm;
static HWND hStatus;
int pParts[2];
SetTimer(hWnd,1,Speed,NULL);
GetClientRect(hWnd, &r);
pParts[0]=500;
pParts[1]=1000;
shlagbm.top=Y3;
shlagbm.left=X3;
shlagbm.bottom=Y3+215;
shlagbm.right=X3+215;
car1.left=X2;
car1.top=Y2;
car1.right=X2+96+13;
car1.bottom=Y2+168+13;
train.left=X-10;
train.top=Y;
train.right=X+538;
train.bottom=Y+118;
Y=85;
switch(msg)
{
case WM_CREATE:
WS_VISIBLE, «Готово», hWnd, ID_STATUS);
SendMessage(hStatus, SB_SETPARTS, 2, (LPARAM)pParts);
return 0;
case WM_NOTIFY:
{
LPTOOLTIPTEXT t;
t=(LPTOOLTIPTEXT)lParam;
if (t->hdr.code!=TTN_NEEDTEXT)
return 0;
switch (t->hdr.idFrom)
{
case IDM_START:
t->lpszText=»Стартпоїзда»;
break;
case IDM_EDIT:
t->lpszText=»Керуванняшлагбаумом»;
break;
case IDM_INFO:
t->lpszText=»Інформаціяпровиконавця»;
break;
case IDM_EXIT:
t->lpszText=»Вихід»;
break;
}
}
case WM_Paint:
{
PAINTSTRUCT ps; // структурадляпараметрівконтексту
hdc = BeginPaint(hWnd, &ps); // отримуємохендлконтекступристрою
hBmpBckGrnd = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
GetObject ( hBmpBckGrnd, sizeof(BITMAP),&bitmap); // отрималирозміризображення
hCompDC = CreateCompatibleDC ( hdc );
oBitmap = (HBITMAP)SelectObject ( hCompDC, hBmpBckGrnd );
// ввели наше зображення у контекст в пам’яті
// і запам’ятали те, що витіснили звідти
StretchBlt (hdc, r.left, r.top, r.right, r.bottom, // куди
hCompDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, // звідки
SRCCOPY); // як
// “натягнули” зображення в пам’яті на екран
SelectObject ( hCompDC, oBitmap );// повернули в контекст в пам’яті попередній вміст
DeleteObject ( hBmpBckGrnd ); // знищилиоб’єкт
if (car==0)
{
hBmpCar1 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP4));
DrawTransparentBitmap(hdc,// Конечный DC.
hBmpCar1,// Битмап, которыйбудетнарисован.
X2, // координата X.
Y2, // координата Y.
0x00FFFFFF); // цвет для прозрачных
// пикселей (в этом случае белоснежный
DeleteObject ( hBmpCar1 ); // знищилиоб’єкт
}
if (car==1)
{
hBmpCar1 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP10));
DrawTransparentBitmap(hdc, // Конечный DC.
hBmpCar1, // Битмап, которыйбудетнарисован.
X2, // координата X.
Y2, // координата Y.
0x00FFFFFF); // цвет для прозрачных
// пикселей (в этом случае белоснежный
DeleteObject ( hBmpCar1 ); // знищилиоб’єкт
}
if(par==1)
{
SendMessage(hStatus, SB_SETTEXT, 0, (LONG)»Увага!!!ЇдеПоїзд!!!»);
hBmpTrain = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP2));
DrawTransparentBitmap(hdc, // Конечный DC.
hBmpTrain, // Битмап, которыйбудетнарисован.
X, // координата X.
Y, // координата Y.
0x00FFFFFF); // цвет для прозрачных
// пикселей (в этом случае
DeleteObject ( hBmpTrain ); // знищилиоб’єкт
}
else
SendMessage(hStatus, SB_SETTEXT, 0, (LONG)»Поїздщедалеко :)»);
if(shlagbaym==0)
{
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)»Увага! Шлагбаумвідкрито!»);
if (w==0)
{
InvalidateRect(hWnd, &shlagbm, FALSE);
w++;
}
hBmpShlagbaym = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP9));
DrawTransparentBitmap(hdc, // Конечный DC.
hBmpShlagbaym,// Битмап, которыйбудетнарисован.
X3, // координата X.
Y3, // координата Y.
0x00FFFFFF); // цвет для прозрачных
// пикселей (в этом случае белоснежный
DeleteObject ( hBmpShlagbaym ); // знищили о’єкт
}
if(shlagbaym==1)
{
SendMessage(hStatus, SB_SETTEXT, 1, (LONG)»Увага! Шлагбаумзакрито!»);
if (w==1)
{
InvalidateRect(hWnd, &shlagbm, FALSE);
w—;
}
hBmpShlagbaym = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP5));
DrawTransparentBitmap(hdc, // Конечный DC.
hBmpShlagbaym,// Битмап, которыйбудетнарисован.
X3, // координата X.
Y3, // координата Y.
0x00FFFFFF); // цвет для прозрачных
// пикселей (в этом случае белоснежный
DeleteObject ( hBmpShlagbaym ); // знищили о’єкт
}
DeleteDC ( hCompDC );
EndPaint(hWnd, &ps); // знищуємо контекст пристрою
return 0;
}
case WM_TIMER:
{
if ((shlagbaym==0)||(Y2<330)||(Y2>350))
{
if (car==0)
{
Y2-=13;
InvalidateRect(hWnd, &car1, FALSE);
}
if (car==1)
{
if (wham==0)
SND_ASYNC);
wham++;
X2+=13;
InvalidateRect(hWnd, &car1, FALSE);
}
if ((Y2<-200)||(X2>1000))
{
Y2=800;
X2=450;
}
}
if (par==1)
{
X+=10;
InvalidateRect(hWnd, &train, FALSE);
if(X<=(X2+45)&&(X+538)>=(X2-1)&&(Y+118)>=(Y2+1)&&(Y<=Y2+85))
car=1;
if (X>1001)
{
X2=450;
par=0;
car=0;
wham=0;
}
}
return 0;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDM_EXIT:
MB_SYSTEMMODAL);
if (k==IDOK) DestroyWindow(hWnd);
break;
case IDM_VARIANT:
{
DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hWnd, DlgProg2);
return 0;
}
case IDM_INFO:
{
DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG3), hWnd, DlgProg3);
return 0;
}
case IDM_EDIT:
{
int i=0;
i=1;
DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProg);
InvalidateRect(hWnd, &shlagbm, FALSE);
return 0;
}
case IDM_HELP:
{
DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG4), hWnd, DlgProg4);
return 0;
}
case IDM_START:
SND_ASYNC);
InvalidateRect(hWnd, &r, FALSE);
X=-500;
par=1;
car=0;
X2=450;
wham=0;
return 0;
}
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc (hWnd, msg, wParam, lParam);
}
BOOL CALLBACK DlgProg(HWND hdWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
{
EndDialog(hdWnd, 0);
return 1;
}
case WM_COMMAND:
{
switch (wParam)
{
case IDC_UPBUTTON:
{
if (par!=1)
{
shlagbaym=0;
}
EndDialog(hdWnd, 0);
return 1;
}
case IDC_DOWNBUTTON:
{
shlagbaym=1;
EndDialog(hdWnd, 0);
return 1;
}
}
return 1;
}
}
return 0;
}
BOOL CALLBACK DlgProg2(HWND hdWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
{
EndDialog(hdWnd, 0);
return 1;
}
}
return 0;
}
BOOL CALLBACK DlgProg3(HWND hdWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
{
switch (wParam)
{
case IDOK:
{
EndDialog(hdWnd, 0);
return 1;
}
}
return 1;
}
case WM_CLOSE:
{
EndDialog(hdWnd, 0);
return 1;
}
}
return 0;
}
BOOL CALLBACK DlgProg4(HWND hdWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
{
switch (wParam)
{
case IDOK:
{
EndDialog(hdWnd, 0);
return 1;
}
}
return 1;
}
case WM_CLOSE:
{
EndDialog(hdWnd, 0);
return 1;
}
}
return 0;
}
void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, short xStart,
short yStart, COLORREF cTransparentColor)
{
BITMAP bm;
COLORREF cColor;
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
hdcTemp = CreateCompatibleDC(hdc);
SelectObject(hdcTemp, hBitmap); // Выбираембитмап
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
ptSize.x = bm.bmWidth; // Получаемширинубитмапа
ptSize.y = bm.bmHeight; // Получаемвысотубитмапа
DPtoLP(hdcTemp, &ptSize, 1); // Конвертируем из координат
// устройства в логические
// точки
// Создаём несколько DC для хранения временных данных.
hdcBack = CreateCompatibleDC(hdc);
hdcObject = CreateCompatibleDC(hdc);
hdcMem = CreateCompatibleDC(hdc);
hdcSave = CreateCompatibleDC(hdc);
// Создаём битмап для всякого DC.
// Монохромный DC
bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
// Монохромный DC
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
// В любом DC должен быть избран объект битмапа для хранения
// пикселей.
bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);
bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);
bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);
// Устанавливаемрежиммаппинга.
SetMapMode(hdcTemp, GetMapMode(hdc));
// Сохраняем битмап, переданный в параметре функции, потому что
// он будет изменён.
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
// Устанавливаем фоновый цвет (в начальном DC) тех частей,
// которые будут прозрачными.
cColor = SetBkColor(hdcTemp, cTransparentColor);
// Создаём маску для битмапа путём вызова BitBlt из начального
// битмапа на монохромный битмап.
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
SRCCOPY);
// Устанавливаем фоновый цвет начального DC назад в
// уникальный цвет.
SetBkColor(hdcTemp, cColor);
// Создаём инверсию маски.
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
NOTSRCCOPY);
// Копируем фон головного DC в конечный.
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart,
SRCCOPY);
// Накладываем маску на те места, где будет помещён битмап.
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
// Накладываем маску на прозрачные пиксели битмапа.
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
// XOR-им битмап с фоном на конечном DC.
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
// Копируем на экран.
BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,
SRCCOPY);
// Помещаем уникальный битмап назад в битмап, переданный в
// параметре функции.
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
// Удаляем битмапы из памяти.
DeleteObject(SelectObject(hdcBack, bmBackOld));
DeleteObject(SelectObject(hdcObject, bmObjectOld));
DeleteObject(SelectObject(hdcMem, bmMemOld));
DeleteObject(SelectObject(hdcSave, bmSaveOld));
// Удаляем DC изпамяти.
DeleteDC(hdcMem);
DeleteDC(hdcBack);
DeleteDC(hdcObject);
DeleteDC(hdcSave);
DeleteDC(hdcTemp);
}
]]>