Міністерство освіти і науки України
Вінницький національний технічний університет
Інститут інформаційних технологій та комп’ютерної інженерії
Кафедра ОТ
Розробка системних об’єктно-орієнтованих програм мовоюС++ в середовищі Windows
(з використанням бібліотеки MFC пакету Visual Studio 2008)
Пояснювальна запискадо курсової роботи з дисципліни
«Системне програмне забезпечення»
Керівник курсової роботи
ст. викл. Снігур А.В.
Розробив студент групи 2КС-06
Мандро О.М.
Вінниця ВНТУ 2008
АНОТАЦІЯ
Дана курсова робота розроблена за допомогою сучасної об’єктно-орієнтовної мови програмування С++ на Visual Studio 2008. В ній був розроблений проект, що використовує бібліотеки MFC. Він містить головне меню, рядок стану, панель інструментів і контекстне меню. Бібліотека, що динамічно підключається до головного проекту, знаходить рішення функції згідно індивідуального завдання. Дана бібліотека написана мовою програмування Assembler та під’єднана до головного проекту як динамічна бібліотека DLL. Дані для виконання обчислень вводяться в діалоговому вікні. Результати роботи програми виводяться в числовому та графічному вигляді в різних діалогових вікнах. Головна програма виконує операції з файлами: відкриття(відкриття текстового файлу), зберігання(зберігання результатів роботи програми) та закриття(закриває головну програму)[10].
ЗМІСТ
ВСТУП
1. АНАЛІЗ ІНДИВІДУАЛЬНОГО ЗАВДАННЯ
2.ЗАГАЛЬНА СТРУКТУРА КУРСОВОЇ РОБОТИ
3.РОЗРОБКА МЕНЮ ПРОГРАМИ
3.1 Головне меню програми
3.2 Таблиця акселератора
3.3 Контекстне меню програми
4.ПАНЕЛЬ ІНСТРУМЕНТІВ ТА РЯДОК СТАНУ
4.1 Створення панелі інструментів
4.2 Рядок стану
5.СТВОРЕННЯ ДІАЛОГОВИХ ВІКОН
5.1 Етапи розробки діалогових вікон
5.2 Створення діалогу
6. РЕАЛІЗАЦІЯ МАТЕМАТИЧНОЇ ФУНКЦІЇ МОВОЮ ASSEMBLER
7.СТВОРЕННЯ ТА ПІДКЛЮЧЕННЯ БІБЛІОТЕКИ DLL
8 РОБОТА З ФАЙЛАМИ
8.1 Відкриття файлу
8.2 Збереження файлу
9. ВИВЕДЕННЯ РЕЗУЛЬТАТІВ ОБЧИСЛЕНЬ
9.1 Числове виведення результату
9.2 Графічне виведення результату
10.КЕРІВНИЦТВО СИСТЕМНОГО ПРОГРАМІСТА
11.КЕРІВНИЦТВО ОПЕРАТОРА
ВИСНОВКИ
ЛІТЕРАТУРА
Додаток А
Додаток Б
ВСТУП
Сучасною прогресивною технологією програмування є об`єктно-орієнтоване програмування. До об`єктно-орієнтовних мов програмування відноситься Visual С++. В ньому елементи математичних моделей та компоненти інтерфейсу представляються окремими класами, що включають в себе дані, функції обробники, та механізми взаємозв`язку з бібліотеками.
Об’єктно-орієнтовні мови дозволяють використовувати бібліотеки класів, в яких містяться реалізовані раніше типи для опису стандартних об’єктів, які можуть бути потрібні програмісту при вирішенні певної задачі. Однією з таких бібліотек є MFC, яка містить набір класів для реалізації інтерфейсу вікон та елементів керування в середовищі Windows. Це звільняє програміста від рутинної роботи по переписуванню стандартних функцій. Але при цьому залишається можливість перевизначати деякі методи стандартних класів та додавати нові, для зміни та розширення їх можливостей.
Microsoft Visual Studio призначена для створення додатків – програм, забезпечених всім необхідним для їх роботи: файлами ресурсів, бібліотеками і т.д. У Visual C++ в основному розробляються додатки на основі Microsoft Foundation Class Library – MFC. В цій бібліотеці багато класів, глобальних функцій; вона призначена для спрощення роботи програмістів. Крім того, Visual C++ включає засіб для автоматизованого створення додатків – AppWizard.
Бібліотека MFC розроблялася для спрощення завдань, що стоять перед програмістом. Як відомо, традиційний метод програмування під Windows вимагає написання досить довгих і складних програм, що мають ряд специфічних особливостей. Бібліотека MFC дає змогу швидко та ефективно реалізувати графічний інтерфейс та обробляти потрібні функції та повідомлення[1,4].
Однією з основних переваг роботи з MFC є можливість багатократного використання одного і того ж коду, а також можливість успадкування методівбатьківського класу в класах нащадках.
Інтерфейс, що забезпечується цією бібліотекою, практично незалежний від конкретних деталей, що його реалізовують. Тому програми, написані на основі MFC, можуть бути легко адаптовані до нових версій Windows (на відміну від більшості програм, написаних звичайними методами).
Щоб працювати з бібліотекою MFC в середовищі розробки програм Microsoft Visual Studio C++ необхідно уміти створювати власні класи, розуміти принципи успадкування, створення об’єктів і вміти перевизначити віртуальні функції. Програми, що використовують бібліотеку MFC, звичайно не містять дуже специфічних елементів С++, для їх написання потрібні значні знання в області системного програмного забезпечення, для коректного функціонування програми[10].
1. АНАЛІЗ ІНДИВІДУАЛЬНОГО ЗАВДАННЯ
Дана програма повинна складатись з двох файлів: головного завантажувального файлу типу *.exe та файлу динамічної бібліотеки *.dll, що має знаходитись в тому ж самому каталозі, що й програма. Даний проект повинен видавати інформацію про розробника, забезпечувати введення в діалоговому режимі вхідних даних з клавіатури, виведення результату роботи програми в числовому та графічному вигляді у різних діалогових вікнах, виконувати стандартні операції з файлами: Open, Save, Exit. В файлі *.dll повинна міститись математична функція обчислення математичного виразу із індивідуального завдання, що написана мовою Assembler. Динамічна бібліотека повинна отримувати з основнї програми необхідні їй дані, проводити потрібні обчислення та передавати результат назад у програму типу *.exe.
Для того, щоб можна було керувати процесами, що виконуються проектом, всі необхідні операції мають бути відображені в головному меню, панелі інструментів. Введення самих даних повинно відбуватись у діалоговому вікні. По натисненню кнопки Run має відбутись обмін даними с динамічною бібліотекою та обчислення функції. Результат має виводитись у двох вікнах. В перше вікно повинен виводитись числовий результат, а в друге по натисненню кнопки Result – графічний. Стандартна операція з файлами Open повинна відкривати текстовий файл у окремому вікні. Якщо в цьому текстовому файлі містяться вхідні дані для розрахунків, то програма повинна оперувати з ними. Операція Save зберігає числовий результат у файлі. При натисненні ж на кнопку Exit програма повинна завершити своє виконання.
2
.
ЗАГАЛЬНА СТРУКТУРА ПРОЕКТУ
Курсова робота складається з двох проектів, що створені за допомогою пакету програм Microsoft Visual Studio 2008. Перший проект використовується для створення DLL
бібліотеки. Він складається з безпосередньо самого файлу з текстом програми – MandroDLL.cpp
, файлів проекту, що автоматично створюються середовищем та файлу MandroDLL.def
в якому вказується ім'я бібліотеки що створюється, та ім'я функції що експортується, яка прописується відповідно синтаксису calc @1
з вказанням номеру функції (@1
).
Другий проект використовується для створення *.exe файлу головної програми, яка використовує створену Dll
бібліотеку. Цей проект включає файл з текстом самої програми – Mandro.CPP
, файли проекту, що автоматично створюються середовищем, заголовочний файл Resource.h
, файл ресурсів Mandro.rc
, а також файли типу *.bmp
та *.ico,
що містять рисунок меню та значок програми відповідно. Загальна структура програми в Visual Studio 2008 зображено на рисунку 1[10].
Рисунок 1 – Загальна структура програми
В основній програмі використовується наступні класи:
1) CMyFrameWin,
CTextWnd
, CGraphdWnd,
які є похідними від бібліотечного класу CFrameWnd
і використовуються для створення основного вікна і вікна для виведення числового і графічного результату;
class CMyFrameWin:public CFrameWnd
class CTextWnd:public CFrameWnd
class CGraphWnd:public CFrameWnd
2) клас CMyDialog – похідний від класу CDialog і використовується для створення діалогового вікна і введення даних;
class CMyDialog:public CDialog
3) контекстне меню створюється за допомогою класу CMenu
:
CMenu menu;
4)клас CStatusBar
для об’єкта – рядка стану
CStatusBar m_wndStatusBar;
5) конструктори класу CFileDialog
– DlgOpen
і DlgSave
- для роботи з файлами, а саме для відкриття і збереження файлів.
6) клас CClientDC
– клас контексту пристрою для забезпечення доступу до робочої області вікна.
CClientDC myDC(TextWnd);
7) клас CAboutDlg– похідний від класу CDialog і використовується для створення діалогового вікна з інформацією про розробника.
class CAboutDlg : public Cdialog
3. РОЗРОБКА МЕНЮ ПРОГРАМИ
3.1 Головне меню програми
В усіх програмах меню розташовується у верхній частині вікна під заголовком програми. Елементи меню призначені для виконання певних команд. Меню, яке розташоване під смугою заголовка вікна, називається головним меню додатку.
Процес створення меню складається із трьох етапів [4,8]:
- створення шаблона меню;
- підключення ресурсу меню до головної програми;
- обробка повідомлень від команд меню.
Створення шаблона меню відбувається добавленням нового ресурсу в пункті меню Edit - Add Resource. При добавленні нового меню воно добавляться в пункт Menu на вкладці Resource View – Mandro[10].
На рис. 2 зображено діалогове вікно Add Resource і вкладка Resource View – Mandro.
Рисунок 2 – Діалогове вікно Add Resource і вкладка Resource View – Mandro
Після добавлення нового меню, йому присвоюється ідентифікатор IDR_MAINFRAME і мова оформлення меню [Английский(США)], оскільки згідно з індивідуальним завданням пункти меню на англійській мові.
Акселератор (клавіша виклику) – повідомляє користувача, що замість виклику меню можна викликати команду за допомогою акселератора(«гаряча клавіша»).
На рис. 3 зображено створений шаблон меню згідно з завданням в індивідуальному завданні.
Рисунок 3 – Візуальний шаблон меню
Після візуального створення шаблону меню кожен його пункт отримує певні атрибути. Зовнішній вигляд вікна властивостей, що визначає атрибути, приведений на рис. 4.
Рисунок 4 – Атрибути меню в вікні властивостей
Підключення меню в програму базується на використанні методу Create
() класу CFrameWnd
, який створює головне вікно програми. В цьому методі можна вказати спеціальний макрос MAKEINTRESOURCE,
аргументом якого буде ідентифікатор підключаємого ресурсу меню. В результаті отримаємо:
CMyFrameWin::CMyFrameWin()
Create(NULL,"Курсова 2KС-06", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MAINFRAME));
Ідентифікатори меню та всіх пунктів меню мають бути представлені в заголовочному файлі ресурсів Resource.h
:
#define IDR_MAINFRAME 128
#define ID_ RENAME 40002
#define ID_RUN 40003
#define ID_RESULT 40021
Після запуску на виконання в верхній частині клієнтської області вікна можна буде побачити створене меню.
Тепер вже можна перейти до третього етапу створення меню. Обробку повідомлень від команд меню в головному програмному файлі проекту необхідно виконати в такій послідовності.
1) В класі вікна з рамкою CMyFrameWnd
оголосити функції-обробники всіх пунктів меню;
2) Включити в карту повідомлень MESSAGE_MAP
макроси, які зв’язують ідентифікатори кожного пункту меню з функцією-обробником;
3) Написати всі функції-обробники, які були вказані в класі вікна з рамкою CMyFrameWnd
та карті повідомлень MESSAGE_MAP
[1].
class CMyFrameWin:public CFrameWnd
public:
CMyFrameWin();
CMenu PopupMenu;
protected:
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
HICON m_hIcon;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnOpen();
afx_msg void OnHelp();
DECLARE_MESSAGE_MAP();
BEGIN_MESSAGE_MAP(CMyFrameWin, CFrameWnd)
ON_WM_CREATE()
ON_COMMAND(ID_OPEN,OnOpen)
ON_COMMAND(ID_HELP1,OnHelp)
END_MESSAGE_MAP();
void CMyFrameWin::OnRun()
void CMyFrameWin::OnAbout()
3.2 Таблиця акселератора
Для прискорення доступу до елементів меню за допомогою клавіатури, а також для виклику потрібних функцій, не пов'язаних з меню, в Windows використовується таблиця акселераторів. Вона знаходиться в ресурсах додатку і визначає відповідність між акселератором і значенням параметра WM_COMMAND, що передається у функцію, при натисненні комбінації клавіш[10].
Щоб комбінація клавіш стала працювати як акселератор, вона повинна бути описана в таблиці акселераторів і додаток повинен завантажити таблицю акселераторів з ресурсів.
Створення таблиці відбувається добавленням нового ресурсу Accelerator в пункті меню Edit - Add Resource, як показано на рис. 2.
Для завантаження таблиці акселераторів використовується функція:
this->LoadAccelTable(MAKEINTRESOURCE(IDR_MAINFRAME));
Зовнішній вигляд вікна властивостей акселератора показано на рис. 5.
Рисунок 5 – Вікно властивостей акселератора для меню About
По замовчуванню, коли клавіша акселератора відповідає пункту меню, система виділяє цей пункт меню.
Зовнішній вигляд таблиці акселератора зображено на рис. 6.
Рисунок 6 – Таблиця акселератора для всієї програми
3.3 Контекстне меню програми
Контекстне меню створюється за допомогою класу CMenu:
CMenu menu;
Але CMenu по замовчуванню не створює меню. Для його створення необхідно скористатись функцією CreatePopupMenu().
menu.CreatePopupMenu();
Щоб додати елементи в контекстне меню, потрібно виконати наступне:
PopupMenu
.CreatePopupMenu();
CPoint p;
GetCursorPos(&p);
PopupMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x, p.y, this);
Метод LoadMenu
зв’язує об’єкт з створеним раніше візуальним меню.
PopupMenu.LoadMenu(IDR_MENUPOPUP);
Стан елемента задається параметром nFlags
, що може утримувати одно або декілька значень.
Контекстне меню створюється так само як головне меню добавленням нового ресурсу Menu пункті меню Edit - Add Resource, як показано на рис. 2.
Зовнішній вигляд контекстного меню показано на рис. 7.
Рисунок 7 – Контекстне меню програми
4
.
ПАНЕЛЬ ІНСТРУМЕНТІВ ТА РЯДОК СТАНУ
4.1 Створення панелі інструментів
Панель інструментів являє собою набір растрових кнопок одного розміру(за замовчуванням їх розміри 15х16) і розподілювачів. Натиснення на кнопку панелі інструментів подібно вибору одного пункту меню. Частіше за все панель інструментів використовується разом з меню, дублюючи основні його пункти. На відміну від меню, вона більш зручна в роботі завдяки додатковим властивостям: організації підказок, встановленню різноманітних стилів і розмірів кнопок тощо.
Щоб створити панель інструментів необхідно натиснути правою кнопкою миші на папці Toolbar
в вікні Resource View
, а потім вибрати із контекстного меню Insert Toolbar
, в результаті чого буде створена нова панель інструментів(створюється пуста панель інструментів).При її створені необхідно задати відповідний ідентифікатор ID
,
наприклад: IDR_MAINFRAME.
Після цього панель інструментів слід заповнити кнопками. Для цього існує спеціальний редактор. При створенні кнопки їй необхідно присвоїти ідентифікатор. В кожній кнопці даної програми прописані підказки у полі Prompt
в діалоговому вікні властивостей кнопок, як показано на рис. 8.
Рисунок 8 – Властивості панелі інструментів
Рисунок 9 – Створення панелі інструментів
По закінченні створення панелі інструментів переходимо до створення програмного коду, що буде обробляти виклики з панелі інструментів. Потрібно додати в клас рамки вікна клас панелі інструментів:
CToolBar m_wndToolBar;
В функції CMyFrameWin::OnCreate(LPCREATESTRUCT lpCreateStruct)
напишемо код для створення панелі інструментів:
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD
|WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS
| CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
TRACE0("Failed to create toolbar\n");
return -1;
де, TBSTYLE_FLAT
– стиль кнопки; WS_CHILD,WS_VISIBLE, CBRS_TOP,CBRS_GRIPPER,CBRS_TOOLTIPS,CBRS_FLYBY,CBRS_SIZE_DYNAMIC
– стилі панелі інструментів.
4.2 Рядок стану
Рядок стану розташовується в нижній частині вікна. Його призначення – відображати опис команд і стан кнопок Num Lock, Caps Lock і Scroll Lock, та інформувати користувача про стан визначених атрибутів або параметрів програми.
Для створення рядка стану необхідно виконати такі кроки.
1. В класі вікна програми оголосити змінну класу CStatusBar
для об’єкта рядка стану:
CStatusBar m_wndStatusBar;
2. Створити структуру з ідентифікаторами полів, що відображаються в рядку стану:
static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_NUM,
ID_INDICATOR_CAPS,
ID_INDICATOR_SCRL,
3. В функції OnCreate CMyFrameWin
код для створення панелі інструментів:
!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
Зовнішній вигляд рядка стану зображено на рис. 9.
Рисунок 9 – Зовнішній вигляд рядка стану
5
.
СТВОРЕННЯ ДІАЛОГОВИХ ВІКОН
5.1 Етапи розробки діалогових вікон
Діалогове вікно має всі ознаки звичайного. Його можна переміщувати, закривати, а також передавати йому повідомлення. Перевага діалогового вікна в тому, що в ньому можна легко розмістити кнопки, текстові поля та інші елементи керування.
Створення діалогового вікна починається з створення класу діалогу. Даний клас є похідним від класу CDialog
.В цьому класі мають бути оголошені необхідні змінні і властивості класу діалогу, які відповідають різним елементам керування діалогового вікна. Далі відбувається ініціалізація елементів керування діалогового вікна. Ініціалізація елементів керування відбувається за допомогою стандартного методу OnInitDialog
(). Після цього створюється об’єкт власного класу діалогу методом DoModal
() та його активувати. Необхідно створити обробку введених користувачем даних в діалоговому вікні. Обробка відбувається після натиснення кнопки Ok
та закриття діалогового вікна. Після цього відбувається передача даних із елементів керування у змінні класу діалогу згідно з DDX-макросами методу DoDatаExchange
(). Якщо введені дані не потрібно зберігати або обробляти, тоді діалогове вікно закривається натисненням кнопки Cancel
. Введені за допомогою діалогового вікна дані далі можуть бути використані в інших функціях програми.
Використовуючи стандартний метод опису діалогу було написано два діалогових вікна: Input і About.
5.2 Створення діалогу
Створення діалогово вікна відбувається добавленням нового ресурсу Dialog пункті меню Edit - Add Resource, як показано на рис. 2.
Діалогове вікно оформляється за допомогою панелі інструментів Toolbox і властивостей даного елементу панелі інструментів, рис. 10.
Рисунок 10 – Панель інструментів Toolbox і вікно властивостей кнопки “OK”
Діалогове вікно запускається по натисненню кнопки Input
. Функція виклику діалогового вікна прописана в функції-обробнику OnInput()
:
void CMyFrameWin::OnInput()
CMyDialog dialog;
dialog.DoModal();
Після цього створюється об’єкт власного класу діалогу методом DoModal
() та його активація. Необхідно створити обробку введених користувачем даних в діалоговому вікні. Обробка відбувається після натиснення кнопки Ok
та закриття діалогового вікна.
void CMyDialog::OnOK()
char str[80];
edit1.GetWindowText(str,80);
for(int i=0;i<=strlen(str);i++)
T=T+str[i];
for(int i=0;i<80;i++)
CDialog::OnOK();
void CMyDialog::OnCancel()
CDialog::OnCancel();
Після цього відбувається передача даних із ЕК у змінні-властивості класу діалогу згідно з DDX-макросами методу DoDataExchange
().
void CMyDialog::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, edit1);
DDX_Control
– покажчик на об’єкт класу елементаму керування.
Якщо введені дані не потрібно зберігати або обробляти, тоді діалогове вікно закривається натисненням кнопки Cancel
[1]. Введені за допомогою діалогового вікна дані далі можуть бути використані в функціях інших класів програми. Діалогове вікно даної програми зображене на рисунку 11.
Рисунок 11 – Діалог для введення даних
В функції OnInitDialog()
проведено початкову ініціалізацію для поля edit1
, а саме за допомогою методу SetWindowText(CString("0"))
значення, яке може вводитись користувачем, в даному випадку початкове значення 0.
За допомогою функції GetWindowText
данні з поля Edit
зчитуються в змінні типу char – str
. Потім за допомогою функції atof
перетворюються в дані типу float
.
Аналогічно створювалось інше діалогове вікно, в якому виводилась інформація про розробника програми. Зовнішній вигляд показано на рис. 12.
Рисунок 12 – Зовнішній вигляд діалогу при натисканні на кнопку «Info»
6. РЕАЛІЗАЦІЯ МАТЕМАТИЧНОЇ ФУНКЦІЇ МОВОЮ ASSEMBLER
При програмуванні математичного співпроцесора може бути використано або програмування співпроцесора для роботи з числами з фіксованою комою, або програмування співпроцесора – з числами з плаваючою комою. В даній програмі використовується програмування співпроцесора для роботи з плаваючою комою. Він має вісім регістрів, які організовані у вигляді стека.(рисунок 13)[8].
Рисунок 13 – Організація стека математичного співпроцесора
Основні команди, що використовуються при програмуванні:
- Finit – команда ініціалізації;
- Fcom src – порівняти значення першого регістру з другим;
- Fld src – завантажити регістр;
- Fst dst – зберегти значення у регістр;
- Fadd dst, src – додати до першого регістра другий;
- Fmul dst, src – помножити перший регістр на другий і зберегти результат в першому;
- Fdiv dst, src – поділити перший регістр на другий і зберегти результат в першому[6].
Всі данні необхідні для обчислення, ініціалізація програми, та вивід данних здійснюється за допомогою C++:
Розглянемо частину коду яка виконує обчислення коли х=4:
_asm
{
FINIT;
FLDE;//ST(6)
FLD D;//ST(5)
FLD A;//ST(4)
FLD B;//ST(3)
FLD C;//ST(2)
FLD X;//ST(1)
FLD Y;//ST(0)
FADD ST(0),ST(1);//Y=X
FMUL ST(0),ST(4);//Y=X*A
FXCH ST(5);//D=A*X
FADD ST(0),ST(1);//Y=X
FMUL ST(0),ST(3);//Y=X*B
FXCH ST(6);//E=X*B
FADD ST(0),ST(3);//Y=B
FMUL ST(0),ST(4);//Y=A*B
FADD ST(0),ST(5);//Y=A*X+A*B
FSUB ST(0),ST(6);//Y=A*X+A*B-B*X
FSTY; вивантажуємо ST(0) в Y
};
7. СТВОРЕННЯ ТА ПІДКЛЮЧЕННЯ БІБЛІОТЕКИ DLL
Бібліотеки DLL – це програмний код або дані, які динамічно доступні всім процесам операційної системи[5].
Динамічне завантаження DLL дозволяє програмі визначити, яка з бібліотек і коли буде завантажуватись, а також задати дію при невдалому завантаженні бібліотеки. Спочатку необхідно помістити модуль бібліотеки в пам’ять процесу. Дана операція виконується за допомогою функції LoadLibrary()
, що має один аргумент – ім'я завантажуваного модуля.
HINSTANCE hDll;
hDll=::LoadLibrary("MandroDLL");
Опрацювання помилки завантаження DLL та повідомлення про помилку:
if (LoadLibrary("MandroDLL ") == NULL)
MessageBox("Cannot find or open file MandroDLL ");
Стандартним розширення ім’я бібліотеки вважається .dll, якщо не вказувати інше. Так як в імені файлу вказано лише його назву, то цей файл повинен знаходитись в одному каталозі з основним файлом типу *.exe. Для визначення адрес окремих функцій всередині бібліотеки використовується функція GetProcAddress()
:
FUN func;
func=(FUN)::GetProcAddress(hDll,"calc");
Для вивантаження бібліотеки з пам'ятті процесу використовується функція FreeLibrary().
Для створення самої бібліотеки DLL був створений новий проект типу Win32 Dynamic-Link Library
та вибраний перемикач Simply DLL.
В результаті було автоматично створено файл, що містить функцію DllMain
(), яка є одночасно і функцією входу, і функцією виходу:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
return TRUE;
}
Далі у файлі бібліотеки DLL описана експортована функція. Дана функція має повертати значення змінної «Y». Для цього слід функцію main()
замінити на функцію, ім'я якої ми використовуємо для визначення адрес:
float Calc(float X)
Експортованій функції з головної програми передається операнди типу float
.
Слід записати, що буде повернуто до основної програми:
return Y;
Ім’я експортованої функції потрібно вказати в окремому файлі визначень (файл типу *.def)[1]. Цей файл необхідно приєднати до проекту.
В текстовому редакторі в цьому файлі набрати текст файлу визначень:
LIBRARY "MandroDLL"
DESCRIPTION 'This library has one function'
EXPORTS
calc @1
У файлі визначень вказується ім’я експортованої функції та її номер, по якому функцію теж можна викликати[1].
Скомпільований файл необхідно скопіювати до каталогу, в якому знаходиться основна програма.
Лістинг бібліотеки наведено в Додатку Б.
8. ОСНОВНІ ОПЕРАЦІЇ НАД ФАЙЛАМИ
8.1 Відкриття файлу
Клас CFileDialog
забезпечує створення і функціонування двох діалогових вікон, що використовуються для відкриття та збереження файлів[11].
Для відкриття файлу використовується конструктор класу:
CFileDialog dlgOpen(TRUE, "txt","", OFN_HIDEREADONLY, "Text file (*.txt)| *.txt| ALL Files(*.*)|*.*|", this);
Діалогове вікно, що відкриває текстовий файл на рис. 14.
Рисунок 14 – Діалогове вікно «Открыть»
Для створення об’єкта Windows потрібно використати метод DoModal
з наступним прототипом:
virtual int DoModal();
Цей метод повертає значення IDOK
або IDCANCEL
, в залежності від того, які кнопки були натиснуті при закриті діалогового вікна[4]. Коли файл відкривається на читання, його режим також повинен бути вказанним на читання:
CFile::modeRead|CFile::typeBinary);
Для виведення данних відкриваємого файлу створено цикл, в якому виділяється необхідна кількість рядків для тексту.
dc.SetTextColor(RGB(255,0,0));
while(File.ReadString(m_Text))
dc.TextOut(10,0,Text,Text.GetLength());
OpenWnd -> UpdateWindow();
File.Close();
Завдяки функції file.ReadString(m_Text);
відбувається зчитування файлу. dc.SetTextColor(RGB(255,0,0)); –
вказує стиль, в якому буде виведено на екран текст. Діалогове вікно, що відображає вміст файлу з даними для обчислення на рис. 15.
Рисунок 15 – Діалогове вікно «Відкрити файл»
8.2 Збереження файлу
Якщо змінити в конструкторі класу TRUE
на FALSE,
то отримається конструктор класу для збереження файлу[11]:
CFile DialogDlgSave(FALSE,"txt","",OFN_HIDEREADONLY,"Text file (*.txt)|*.txt| All Files(*.*)|*.*|",this);
де OFN_HIDEREADONLY
– знімає прапорець Read-Only
;
OFN_CREATEPROMPT
– дозволяє створення неіснуючих файлів.
Діалогове вікно, що зберігає результати виконання програми в текстовий файл на рис. 16.
Рисунок 16 – Діалогове вікно «Сохранить как»
Для запису даних використовується наступна конструкція:
CStdioFile file(DlgSaveAs.GetPathName(),
CFile::modeCreate|CFile::modeWrite);
Функція GetPathName()
повертає ім’я вибраного файла та шлях. modeWrite
– довзоляє створювати файл на запис.
В данній програмі відбувається збереження результату обчислення в тектсовому файлі. Це реалізується за допомогою:
CString string=”Результат обрахувань програми:";
string+=s;
File.WriteString(LPCSTR(string));
Завдяки функції File.WriteString(LPCSTR(string)
відбувається запис до файлу.
Результати виконання програми зберігаються в текстовий файл, як показано на рис. 17.
Рисунок 17 – Діалогове вікно, що відображає вміст файлу
9. ВИВЕДЕННЯ РЕЗУЛЬТАТІВ ОБЧИСЛЕНЬ
9.1 Числове виведення результату
Числовий результат роботи програми виводиться у окремому вікні. Для цього був створений новий клас CTextWnd:
class CTextWnd:public CFrameWnd
public:
CTextWnd(CWnd *wnd);
Для створення нового вікна використовується метод Create:
CTextWnd::CTextWnd(CWnd *WndParent)
CRect rect(200,200,500,500);
Create (NULL,"Текстовий результат", WS_OVERLAPPEDWINDOW, rect, WndParent, NULL);
Власне виведення результату описане в функції OnResult
()(рисунок 18):
CClientDC DC(TextWnd);
DC.SetTextColor(RGB(13,66,6));
Виконуємо виведення результату за допомогою функції TextOut.
DC.TextOut(125,125,s,strlen(s));
Рисунок 18 – Діалогове вікно числового виведення результату
9.2 Графічне виведення результату
Для всіх пристроїв графічного виведення використовуються одні і ті ж самі функції і класи, а вибір конкретного пристрою система виконує самостійно на основі інформації про контекст пристрою. Особливістю бібліотеки MFC
є те, що вона містить спеціальні класи контекстів пристроїв. Базовим класом для всіх контекстів пристроїв є клас CDC
. Існує також ще декілька класів контекстів пристроїв, що мають більш вузьку спеціалізацію. Я використовував CClientDC,
що являє собою клас контексту пристрою для забезпечення доступу до клієнтської (робочої) області вікна. При створенні об’єкта цього класу в конструкторі викликається API-функція GetDC()
, а при його знищенні в деструкторі – API-функція RealeaseDC()
[7].
Для виведення результатів роботи програми у графічному вигляді було використано можливості векторної графіки.
В окремому вікні зображено знак “>” або “<” і цифра створена масивом точок “4”, знак “>” або “<” залежить від вхідних даних. Також виводиться прямокутник розміри якого залежать від результату обрахувань. Вигляд вікна з графічним результатом зображено на рисунку 19.
CBrush brush,brush2,brush3;
pen.CreatePen( PS_SOLID, 5, RGB( 0, 0, 0));
brush.CreateHatchBrush(HS_DIAGCROSS, RGB( 0, 0, 255));
brush2.CreateSolidBrush(RGB( 255, 0, 0));
brush3.CreateSolidBrush(RGB( 0, 255, 0));
float m=atof(s);
DCS.SelectObject(&brush);
DCS.Rectangle(200-m,500-m,700+m,700);
DCS.SelectObject(&pen);
DCS.SelectObject( &brush3);
if(z<4)
DCS.Polygon(arr,6);
if(z>4)
{
arr[0].x=260;
arr[3].x=340;
DCS.Polygon(arr,6);
};
Елементи масиву, які є вершинами багатокутника формуються таким чином щоб чітко відображалась різниця між знаком “>” і “<” при введенні різних Х. На основі вищезазначеного масиву формують дані для побудови інших фігур.
Рисунок 19 – Діалогове вікно графічного виведення результату
10. КЕРІВНИЦТВО СИСТЕМНОГО ПРОГРАМІСТА
Комп’ютер, на якому працює програма, повинен мати наступні мінімальні конфігурації:
· Процесор Pentium 500 MHz або більше;
· Оперативну пам’ять не менше 256 МБ;
· Не менше 2 ГБ вільного місця на диску;
· ОС Windows ME/2000/XP;
· Монітор з розширенням 800 x 600 та кольоропередачею в 32 біт;
Програма викликається за рахунок запускання її виконуваного файлу Mandro.exe
, що знаходить в папці ALEX_MANDRO\Main\Debug. Для її правильного функціонування необхідно, щоб у папці де знаходиться файл Mandro.exe
також розміщувався файл MandroDLL.dl
, що містить динамічно підключувану бібліотеку, яка використовується при роботі. Файл MandroDLL.dll
знаходиться в папці ALEX_MANDRO\DLL\Debug.
Основними файлами для створення проекту є:
1. Файли для створення основної програми: код програми на С++ - Mandro.cpp; файл ресурсів - Mandro.RC; заготовочний файл для зв’язку з ресурсами – Resource.h і Mandro.sln – основний файл проекту, що містить посилання на необхідні об’єкти. Також до основного проекту потрібно добавити папку з ресурсами RES, що містить малюнки панелі інструментів, іконки програми(toolbar1.bmp, ICON1.ICO).
2. Файли для створення бібліотеки DLL: MandroDLL.sln - основний файл проекту; MandroDLL.cpp - код програми на С++ і Assembler; StdAfx.cpp – файл що підключає файл заголовків StdAfx.h; MandroDLL.def – файл визначень що містить ім’я експортованої функції;.
11. КЕРІВНИЦТВО ОПЕРАТОРА
Дана програма не вимагає попереднього установлення, для її запуску необхідно скопіювати в один каталог головний завантажувальний файл Mandro.exe
, файл динамічно підключуваної бібліотеки MandroDLL.dll
(рис. 20).
Вхідна інформація для обчислення потрапляє в програму з клавіатури: вона вводиться у призначеному для цього діалоговому вікні введення, що відкривається при натисканні кнопки «Input»
. Виведення інформації здійснюється у двох формах. Текстовий результат виводиться при натисненні пункту меню «Run»
, а графічний – «Result»
. Відомості про розробника виводяться при натиснені кнопки «About».
При натиснені на пункт меню «Open», можна відкрити існуючий файл з даними до виконання, записаних у форматі «Х=[числові дані]». Якщо натиснути на пункт меню «Save» чи відповідну йому кнопку на панелі інструментів або комбінацією клавіш Ctrl+S, результати виконання будуть збережені у файл. Щоб вийти з програми необхідно вибрати пункт меню «Exit».
При роботі програми може виникнути таке повідомлення:
Cannot find or open file MandroDLL.dll
–це повідомлення виникає при запуску обчислення функції у разі, коли не знайдено файл динамічної бібліотеки, якому передаються данні для обчислення.
Внаслідок виникнення критичної помилки слід перезавантажити головну програму Mandro.exe
.
Рисунок 20 – Зовнішній вигляд основних файлів проекту
ВИСНОВКИ
У результаті виконання даної курсової роботи було створено програму на мові С++ та з використанням підпрограми на мові програмування Assembler. Основна програма містить системне меню, рядок стану, панель інструментів.
Виконується обчислення функції, що написана мовою програмування Assembler та під’єднана до основного проекту як динамічна бібліотека DLL.
Дані для обчислень в програмі вводяться в діалоговому вікні. Результат обчислень виводиться в окремих вікнах (вивід числового результату та графічного). Програма виконує стандартні операції “Open”, “Save”, “Exit”.
Виконуючи завдання курсової роботи я поглибив свої навички з написання системних об’єктно-орієнтованих програм, навчився створювати складні програми з допомогою бібліотек MFC пакету Microsoft Visual Studio 2008, засвоїв основні принципи створення системних програм для середовища Windows 98/XP, а також вивчив структуру і принцип роботи Windows 98/XP.
ЛІТЕРАТУРА
1.Семеренко В.П., Програмування мовами С та С++ в середовищі Windows.– Вінниця: ВДТУ, 2002 р. –128с.
2. Секунов Н.Ю. Самоучитель Visual C++. – СПб.: БХВ-Петербург , 2002. – 736 с.
3. Шеферд Джордж, Программирование на MicroSoft Visual C++/Пер. с англ, - М.: “Русская Редакція”, 2003.—928с.
4. Крупник А. К., Изучаем Ассемблер.– СПб.:Питер, 2004 г. –256с.
5. Поляков А.К., Брусенцев В.С., Методы и алгоритмы компьютерной графики в примерах на Visual C++.–СПб.:БХВ-Петербург, 2003 г. –560с.
6. Семеренко В.П., Програмування мовами С та С++ в середовищі Windows.– Вінниця: ВДТУ, 2002 р. –128с.
7. Герберт Шилдт. Полный справочник по С.–Київ:Вільямс, 2002г.– 365с.
8. Бурдаев О. В., Иванов М. А., Тетерин И. И.– Ассемблер в задачах защиты информации.–Москва:КУДИЦ-Образ, 2004 г.–320с.
9. Баженова І.Ю., Visual C++ 6.0 Уроки програмування.– Київ:Фоліо,1997. – 634с.
10. http://msdn.microsoft.com/ru-ru/vstudio/default.aspx
11. Lars Powers, Mike Snell, Microsoft Visual Studio 2008 Unleashed, USA, 2008 – 1536c.
ДОДАТОК А
// Mandro.cpp :Defines the class behaviors for the application.
#include <afxwin.h>
#include <afxext.h>
#include "Resource.h"
#include "string.h"
#include "resrc1.h"
CString T="";
char s[80];
//++++++++++++++++++++++++++++++++++++++
class CMyDialog:public CDialog
{
public:
CMyDialog(CWnd* pParent=NULL);
enum {IDD=IDD_DIALOG1};
CEdit edit1;
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
BOOL OnInitDialog();
afx_msg void OnOK();
afx_msg void OnCancel();
DECLARE_MESSAGE_MAP()
};
CMyDialog::CMyDialog(CWnd* pParent)
:CDialog(CMyDialog::IDD, pParent)
{}
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, ID_EDIT1, edit1);
}
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_COMMAND(IDOK,OnOK)
ON_COMMAND(IDCANCEL,OnCancel)
END_MESSAGE_MAP();
void CMyDialog::OnOK()
{
char str[80];
T="";
edit1.GetWindowText(str,80);
for(int i=0;i<=strlen(str);i++)
T=T+str[i];
for(int i=0;i<80;i++)
CDialog::OnOK();
}
void CMyDialog::OnCancel()
{
CDialog::OnCancel();
}
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
edit1.SetWindowText(CString("0"));
return TRUE;
}
//++++++++++++++++++++++++++++
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
//++++++++++++++++++++++++++++++
class CTextWnd:public CFrameWnd
{
public:
CTextWnd(CWnd *Wnd);
};
CTextWnd::CTextWnd(CWnd *WndParent)
{
CRect rect(200,200,500,500);
Create (NULL,"Текстовий результат",WS_OVERLAPPEDWINDOW,rect,WndParent,NULL);
};
class CGraphWnd:public CFrameWnd
{
public:
CGraphWnd(CWnd *Wnd);
};
CGraphWnd::CGraphWnd(CWnd *WndParent)
{
Create (NULL,"Графічний результат", WS_OVERLAPPEDWINDOW, rectDefault,WndParent,NULL);
};
class COpenWnd:public CFrameWnd
{
public:
COpenWnd(CWnd *wnd);
};
COpenWnd::COpenWnd(CWnd *wndParent)
{
CRect rect(300,420,600,620);
Create (NULL,"Відкрити файл",WS_OVERLAPPEDWINDOW,rect,wndParent,NULL);
}
//+++++++++++++++++++++++++++++++
class CMyFrameWin:public CFrameWnd
{
public:
CMyFrameWin();
CMenu PopupMenu;
protected:
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
HICON m_hIcon;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnOpen();
afx_msg void OnSave();
afx_msg void OnInput();
afx_msg void OnRun();
afx_msg void OnResult();
afx_msg void OnExit();
afx_msg void OnAbout();
afx_msg void OnHelp();
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP();
};
BEGIN_MESSAGE_MAP(CMyFrameWin, CFrameWnd)
ON_WM_CREATE()
ON_COMMAND(ID_OPEN,OnOpen)
ON_COMMAND(ID_SAVE,OnSave)
ON_COMMAND(ID_EXIT,OnExit)
ON_COMMAND(ID_INPUT,OnInput)
ON_COMMAND(ID_RUN,OnRun)
ON_COMMAND(ID_RESULT,OnResult)
ON_COMMAND(ID_ABOUT,OnAbout)
ON_COMMAND(ID_HELP1,OnHelp)
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP();
static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
CMyFrameWin::CMyFrameWin()
{
Create(NULL,"Курсова робота ст гр 2КС-06 Мандро Олександра",
WS_OVERLAPPEDWINDOW,rectDefault,NULL,
MAKEINTRESOURCE(IDR_MAINFRAME));
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
SetIcon(m_hIcon, true);
this->LoadAccelTable(MAKEINTRESOURCE(IDR_MAINFRAME));
PopupMenu.LoadMenu(IDR_MENUPOPUP);
};
int CMyFrameWin::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD
| WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS
| CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1;
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1;
}
return 0;
}
void CMyFrameWin::OnOpen()
{
CString Text;
CFileDialog dlgOpen(TRUE, "txt","", OFN_HIDEREADONLY, "Текстовий файл (*.txt)| *.txt| ALL Files(*.*)|*.*|", this);
if(dlgOpen.DoModal()==IDOK)
{
COpenWnd *OpenWnd=new COpenWnd(this);
OpenWnd -> ShowWindow(SW_SHOWNORMAL);
OpenWnd -> UpdateWindow();
CClientDC dc(OpenWnd);
dc.SetTextColor(RGB(45,52,52));
CStdioFile File(dlgOpen.GetPathName(), CFile::modeRead| CFile::typeBinary);
while(File.ReadString(Text))
{
dc.TextOut(10,0,Text,Text.GetLength());
if (Text[0]=='X')
{
int N=2;
while(N!=Text.GetLength())
{
T=T+Text[N];
N++;
}
}
}
OpenWnd -> UpdateWindow();
File.Close();
}
}
void CMyFrameWin::OnSave()
{
CString string="Результати обчислень програми: ";
CFileDialog DlgSave(FALSE,"txt","",OFN_HIDEREADONLY,
"Text file (*.txt)|*.txt|All Files(*.*)|*.*|",this);
string+=s;
if(DlgSave.DoModal()==IDOK)
{
CStdioFile File(DlgSave.GetPathName(),
CFile::modeCreate | CFile::modeWrite);
File.WriteString(LPCSTR(string));
}
}
void CMyFrameWin::OnExit()
{
SendMessage(WM_CLOSE);
}
void CMyFrameWin::OnInput()
{
CMyDialog dialog(this);
dialog.DoModal();
}
void CMyFrameWin::OnRun()
{
float res;
float x=atof(T);
HINSTANCE hDll;
hDll=::LoadLibrary("MandroDLL");
typedef float(*FUN)(float);
FUN func;
func=(FUN)::GetProcAddress(hDll,"Calc");
res=(*func)(x);
sprintf(s,"%f",res);
FreeLibrary(hDll);
CTextWnd * TextWnd=new CTextWnd(this);
TextWnd->ShowWindow(SW_SHOWNORMAL);
TextWnd->UpdateWindow();
CClientDC myDC(TextWnd);
myDC.SetTextColor(RGB(13,66,6));
myDC.TextOut(125,125,s,strlen(s));
}
void CMyFrameWin::OnResult()
{
CGraphWnd * GraphWnd=new CGraphWnd(this);
GraphWnd->ShowWindow(SW_SHOWNORMAL);
GraphWnd->UpdateWindow();
CClientDC DCS(GraphWnd);
float z=atof(T);
CPen pen;
CPoint arr[6];
arr[0].x=100;
arr[0].y=220;
arr[1].x=180;
arr[1].y=100;
arr[2].x=260;
arr[2].y=100;
arr[3].x=180;
arr[3].y=220;
arr[4].x=260;
arr[4].y=340;
arr[5].x=180;
arr[5].y=340;
CBrush brush,brush2,brush3;
pen.CreatePen( PS_SOLID, 5, RGB( 0, 0, 0));
brush.CreateHatchBrush(HS_DIAGCROSS, RGB( 0, 0, 255));
brush2.CreateSolidBrush(RGB( 255, 0, 0));
brush3.CreateSolidBrush(RGB( 0, 255, 0));
float m=atof(s);
DCS.SelectObject(&brush);
DCS.Rectangle(200-m,500-m,700+m,700);
DCS.SelectObject(&pen);
DCS.SelectObject( &brush3);
if(z<4)
{
DCS.Polygon(arr,6);
};
if(z>4)
{
arr[0].x=260;
arr[3].x=340;
DCS.Polygon(arr,6);
};
for (int i=20;i>0;i--)
{
CPoint arr2[10];
arr2[0].x=420+i;
arr2[0].y=260+i;
arr2[1].x=540+i;
arr2[1].y=20+i;
arr2[2].x=620+i;
arr2[2].y=20+i;
arr2[3].x=540+i;
arr2[3].y=180+i;
arr2[4].x=700+i;
arr2[4].y=140+i;
arr2[5].x=760+i;
arr2[5].y=60+i;
arr2[6].x=860+i;
arr2[6].y=60+i;
arr2[7].x=640+i;
arr2[7].y=380+i;
arr2[8].x=560+i;
arr2[8].y=380+i;
arr2[9].x=660+i;
arr2[9].y=200+i;
DCS.SelectObject(&brush2);
DCS.Polygon(arr2,10);
}
CString str1="Результати обрахувань програми: ";
DCS.SetTextColor(RGB(155,100,55));
DCS.TextOut(350,550,str1);
DCS.SetTextColor(RGB(100,155,255));
DCS.TextOut(450,600,s);
pen.DeleteObject();
brush.DeleteObject();
brush2.DeleteObject();
brush3.DeleteObject();
}
void CMyFrameWin::OnAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
void CMyFrameWin::OnHelp()
{
MessageBox(NULL,"Only God can help U","Help",MB_OK|
MB_ICONINFORMATION);
}
void CMyFrameWin::OnRButtonDown(UINT nFlags, CPoint point)
{
CPoint t;
GetCursorPos(&t);
PopupMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,t.x, t.y, this);
}
class CMyApp:public CWinApp
{public:
virtual BOOL InitInstance();
};
BOOL CMyApp::InitInstance()
{
CMyFrameWin *pMainWnd=new CMyFrameWin;
m_pMainWnd=pMainWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
};
CMyApp app;
ДОДАТОК Б
// MandroDLL.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
float Calc(float X)
{
float A(5);
float B(2);
float C(6);
float D(0);
float E(0);
float F(4);
float Y(0);
_asm
{
FINIT;
FLD F;//st(1)=4
FLD X;//st(0)=X
FCOM ST(1)
FSTSW ax
AND EAX ,00004500h
CMP EAX ,00000000h
je M_Bigger;
CMP EAX ,00000100h
je M_Lower;
CMP EAX ,00004000h
je M_Equal;
M_Equal:
Finit
Fld E;//ST(6)
Fld D;//ST(5)
Fld A;//ST(4)
Fld B;//ST(3)
Fld C;//ST(2)
Fld X;//ST(1)
Fld Y;//ST(0)
Fadd ST(0),ST(1);//y=x
Fmul ST(0),ST(4);//y=x*a
Fxch ST(5);//d=a*x
Fadd ST(0),ST(1);//y=x
Fmul ST(0),ST(3);//y=x*b
Fxch ST(6);//e=x*b
Fadd ST(0),ST(3);//y=b
Fmul ST(0),ST(4);//y=a*b
Fadd ST(0),ST(5);//y=a*x+a*b
Fsub ST(0),ST(6);//y=a*x+a*b-b*x
Fst Y;
jmp M_END
M_Lower:
Finit
Fld D;//ST(5)
Fld A;//ST(4)
Fld B;//ST(3)
Fld C;//ST(2)
Fld X;//ST(1)
Fld Y;//ST(0)
Fadd ST(0),ST(1);//y=x
Fmul ST(0),ST(4);//y=x*a
Fxch ST(5);//d=a*x
Fadd ST(0),ST(1);//y=x
Fmul ST(0),ST(3);//y=x*b
Fadd ST(0),ST(5);//y=a*x+b*x
Fsub ST(0),ST(2);//y=a*x+b*x-c
Fst Y;
jmp M_END
M_Bigger:
Finit
Fld D;//ST(5)
Fld A;//ST(4)
Fld B;//ST(3)
Fld C;//ST(2)
Fld X;//ST(1)
Fld Y;//ST(0)
Fadd ST(0),ST(4);//y=a
Fmul ST(0),ST(3);//y=a*b
Fxch ST(5);//d=a*b
Fadd ST(0),ST(1);//y=x
Fmul ST(0),ST(1);//y=x*x
Fmul ST(0),ST(4);//y=x*x*a
Fsub ST(0),ST(5);//y=a*x*x-a*b
Fst Y;
M_END:
}
return Y;
}
|