1. Въведение в Windows


Насочването на съобстенията за обработка



страница4/4
Дата21.07.2017
Размер0.77 Mb.
#26214
1   2   3   4

Насочването на съобстенията за обработка:

Командните съобщения се насочват първо към изгледа и после към документа (той обработва само командхите съобщения), след което ако няма обработка той отива в Template ако и там няма , отиват във Frame, aкo и там няма обработка отиват в Application(обекта приложение) и там ако няма отиват в default (обработват се по подразбиране)


32 Архитектура документ/изображение: клас на приложението и документ шаблон.

Document Template(документен шаблон)

Такъв има всяко приложение. Той е различен в MDI и SDI. Прави връзка между ( при това само по 1) document class , view, frame. Има CSingleDocTemplate и CMultipleDocTemplate.

Съдържа:


  • документен низ (7 полета),

\nMy_app\My_app\n\n\nMy_app.Document\nMy_app Document

  • Иконата на изображението

  • Менюто при активно изображение.

SDI документния шаблон се създава още в InitInstanse():

CSingleDocTemplate * pDocTemplate;

PDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS( CMyDoc), RUNTIME_CLASS( CMainFrame), RUNTIME_CLASS( CMyView));

AddDocTemplate(pDocTemplate);

// следват редове за създаване обектите от шаблона, показване рамката и изгледа. Включва се цикълът за обр. съобщения, като съобщенията се разделят към обектите - приложение, рамка, изглед, документ, прозорец (command routing).

Ако създадем приложение и кажем че разширението е .авс, то след InitInstance(),Windows знае че след като кликнем на файла .авс тотрябва ад се стартира нашето приложение.

Насочването на съобщенията за обработка:

Командните съобщения се насочват първо към изгледа и после към документа (той обработва само командхите съобщения), след което ако няма обработка той отива в Template ако и там няма , отиват във Frame, aкo и там няма обработка отиват в Application(обекта приложение) и там ако няма отиват в default (обработват се по подразбиране)


33.Време на живот на документа и изображението

В SDI има един обект на приложението на документа. Това означава, че за да отвори нов документ трябва да затворим стария.

В MDI имаме много документални обекти, затова не е необходимо припокриване.

1.При избиране на нов се създава нов обект.Ако е ….. Template то се взема от него документен шаблон и се създава , а ако са повече то се извежда та екрана от кой точно шаблон да се вземе.

2.Отваряне на съществуващ документ.

Updating Doc. & Views

Единственото място където класовете документи и изображенията директно си взаимодействат е времето на update. Комуникацията в този период е следната:

GetDocument - връща у-тел към обекта и там могат да се променят

UpdateAllViews - Документния клас съдържа списък с всички свързани с него изображения. Като се извика таз ф-я тя прохожда списъка и вика On-update за всяко view

OnInitialUpdate - първоначална инициализация

OnUpdate - Метод на UpdateAllViews. Прерисува се цялото изображение във View.

Оптимизация: Има възможности свързани с параметрите на UpdateAllViews: Първи: е задължителен pointer към View. Изобр. Където са променени данните няма нужда да се пресисува, OnUpdate тества у-теля дали е негово изобр. Ако не го прескач. Втори: Парам. е скаларна ст-ст , която се подава. Използва се за подаване на индекс на някоя от картинките на обекта. Трети: у-тел към обект. Може да се използва със същата цел. Чрез тез медоди се стремим не да прерисуваме, а да презапишем инфо.

34. Основни View класове към MFC


  1. CView - стандартен дъщерен прозорец за вашето изображение.

  2. CScrollView - добавя scroll възможности към CView .

  3. CformView - предостявя диалог за вграждане на контроли в изображението

  4. CRecordView- Производен на горния, използва се при работа с ODBC БД – изобразява запис от ODBC база данни.

  5. CDaoRecordView- подобен на горния, но за работа с DAO .

  6. CeditView - съдържа edit control, който попълва клиентската област .

  7. CtreeView - съдържа tree view control, койо попълва клиентската област на изображението.

  8. CRichEditView- съдържа rich edit control, който попълва клиентската област на изображението.

  9. CListView- съдържа list control.

  10. CHtmlView създава изгледи от html формати и други формати, поддържани от контрола WebBrouser на Microsoft Internet Explorer.

Ако изображението има масив от обекти то може да се подаде чрез индекс към един от обектите. Тогава OnUpdate ще го тества. Третия индекс е указател към обект.

Ето наследствените връзки м/ду тези класове:

CScrollView

void CMyView::OnInitialUpdate()

{CScrollView::OnInitialUpdate();

SetScrollSizes(MM_TEXT, CSize(1280,1024)); }

При ScrollView най-често трябва да се направят обикновено две неща:

1.Да се опише OnDraw()

2. Да се опише OnInitialUpdate()

Със Csize се задават размерите на изгледа.



Основни ф-ии на класа:

CPoint pos = GetScrollPosition();

ScrollToPosition(CPoint(100,100));

CSize size = GetTotalSize();

//връща лог. размер на изгледа

int nWidth = size.cx;

int nHeight = size.cy;

SetScaleToFitSize(GetTotalSize());

//мащабира лог. изглед .

SetScrollSize(….)



Скролирането се описва в OnDraw

OnDraw(&dc)

Ако искаме OnDraw() да прерисува само инвалидизирания правоъгълник:.

CRect rect;

pDCGetClipBox(&rect); //попълва размера на инвалид. правоъгълник.

Ако използваме CDC то може да се обърнем към..... DC за да настрои изображението.



HTML изгледи: ChtmlView

Визуализира HTML страници. Класа ChtmlView конвертира Web browser контрола в изглед. Web browser контрола е COM обект. ChtmlView може да визуализира HTML код.



Невиртуални операции (готови методи) на класа:

GetBusy - показва дали в момета е download GetLocatinURL

извлича RL адресана текущата страница

GoBack GoForward Refresh Stop преустановява зареждането

Navigate по зададен URL адрес изобразява текуща страница

Пример:


ON_COMMAND(ID_BACK, OnBack) в message map на CmyView ON_COMMAND) ID_REFRESH, OnRefresh)

void CMyView::OnBach()



{ GoBack() }

Преход към друга страница можете да направите:

Navigate( _T(http://www.microsoft.com));

“тънки клиенти”:

void CHtmlClockView::OnInitialUpdate()

{ ….Navigate(string);…



Интересни методи на класа:

::SetImageList()//свързва текста с картинка

::InsertItem() //вмъкване, корен, подредба, картинка и т.н.

::DeleteItem() ::SetItemText() ::SortChildren() ::GetSelectedItem()



Създаване на изгледи, базирани на контроли:

* да се декларира клас, наследник на базов (напр. CctrlView), като в конструктора се подава името на базовия.

* да се опише ф-ия (напр: GetTabCtrl()) връщаща this на обхващания контрол:

CTabCtrl& GetTabCtrl() const {return (CTabCtrl*) this;}

* и да се предефинират поне 2 метода:

CMyView::PreCreateWindow(..)

::OnInitialUpdate()
35.Разлики между SDI и MDI:

1. В MDI има повече от един отворен документ, докато в SDI, за да отвори втори трябва да затворим първия.

2. В MDI могат да се поддържат различни типове документи.

3. При MDI в менюто има опция Windows за превключване на прозорците.

4. MDI има поне 2 менюта , а SDI има едно .Първото при отворен документ, а второто при затворен.

5. В SDI има една рамка, а в MDI има главна и дъщерна рамка.

Множество изгледи под един документ в MDI приложения

Използва се многодокументния шаблон- CMultiDocTemplate. Тъй като документа е същия не се създава нов документ, а само нов изглед. Т.е. документа и рамката си остават същите.MFC осигурява списъчна структура за обхождане на всички изгледи (като например при UpdateAllView). Всеки изглед вика Get Document, за да получи данни.Ако в някое View променим данните и искаме промените да се отразят в други View, налага се да се използва UpdateAllView, който пък вика OnUpdate на всеки View. Този метод не се вика автоматично-ние трябва да го осигурим. UpdateAllView обхожда всеки View и ги обновява, като инвалидизира (Invalidate) целия прозорец. Ако искаме оптимизация ние трябва да променим реализацията на UpdateAllView и по-точно да променим параметрите, с които се вика OnUpdate.


36.Razlichni tipove dokumenti

Документите могат да са от различни типове. Обикновено този процес се стартира от File/New от менюто. Първо трябва да имаме отделен документен шаблон за всеки тип документ.

- създаваме подклас за документ и подклас за изглед - например CPiramDoc и CpiramView. Класовете са динамично създаваеми.

- за новия тип са нужни 4 нови ресурса-икона, меню, таблица и акселератори и документен низ.Всички те имат общ ID – например IDR_PIRAMTYPE.

- ако е нужно се създава и собствена дъщерна рамка за новия тип документ.

- модифицира InitInstance() за новия документен шаблон.

CMultiDocTemplate* pDocTemplate;

pDocTemplate = new CmultiDocTemplate( описаните по-долу 4 параметъра);

- ресурсен ID;

- Указател към CRuntime class (RUNTIME_CLASS() ) за документа.

-Указател към CRuntime class за рамката.

-Указател към CRuntime class за изгледа ( CPiramView).



Регистрираме новия шаблон :

AddDocTemplate( pDocTemplate);

Ако имаме повече документни типове – за всеки в InitInstance() подобен код. CMultiDocTemplate има грижа да организира списъка.

MIDI e единно за това да има повече от една инстанция на документите. Може да са разнотипни. Става с File_new. Трябва да имаме отделен док-тен шаблон за всеки тип. Последователност от дейтвия –ония от горе. InitInstace() – М-д на обекта на приложението. ! да се модифицира. Създаваме обект CmultiDocTemplate. След като се създаде шаблона се правят проверки, ако не е регистриран, го регистрираме



37. Разцепни изображения.

Връзката между елементите на split изображението:



Split линията може да бъде хоризонтална или вертикална. В SDI това е еднствения начин да имаме повече от едно изображение. В SDI прозореца със сплитерите е дъщерен на MainFrame,а в на MDI Childframe.

Има два вида сплитери: динамични и статични.

Динамичните сплитери дават възможност в един прозорез да се наблюдават различни части на обекта. Създават се и се унищожават динамично. Ако разделим хоризонтално, по вертикала ще имаме различни Scrollbars, ако разделяме по вертикала ще имаме 2 различни хоризонтални. Всички панели по подразбиране се базират на едно изображение, но не е невъзможно са де променят. Това става като един сплитер има метод, чрез който всеки оплитер е елемент на различно View. Този метод е на CsplitterView.

Статичните сплитери - в тях панелите се указват преди създаване на приложение и тогава се създават, т.е. броя панели се запазва. Всеки панел се базира на отделно указано изображение (няма подразбиране).

Създаване на приложение поддържащо

динамични сплитери:

1.Деклариране на нова пром. към CChildFrame ( или CMainFrame):



// Implementation

private:

CSplitterWnd m_wndSplitter;

2.Предефиниране на виртуалната OnCreateClient() на рамката :

BOOL CChildFrame:: OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext)

{CSize size (10, 10);

Return m_wndSplitter.Create ( this, 2,1, size, pContext); }

родителя на прозореца със сплитери – прозореца рамка

аксималния брой панели на които може да се раздели

максималната ширина и височина при които панелите се създават

стандартна структура, едно от полетата й е име на класа на изгледа, използван за панелите.

3. CSplitView::OnDraw()

Възможно е да се създадът динамични сплитери в статични.

създаване на прил., поддържащо статично split изображение:

- в класа на прозореца рамка (CMainFrame или CChildFrame): CSplitterWnd m_wndSplitter;

- предефиниране :

BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpc, CreateContext* pContext)

{

if (m_wndSplitter.CreateStatic(this, 2, 1) == FALSE)



// код при неуспех

// следва създаване на изглед за всеки статичен панел от прозореца:

BOOL bCreated = m_wndSplitter.CreateView( 0,0,…);

bCreated = m_wndsplitter.CreateView( 1, 0, RUNTIME_CLASS(CsplitView),…

// коорд. (долу ляво) и изглед за втория split view

);

SetActiveView((CView*) m_wndsplitter.GetPanel(0,0);



//активен панел

Return TRUE;

}
41. Графичен Интерфеис

Всеки изход в Windows е графичен и зависи от устройството на което се извежда. Трябва да изолираме програмата от устройството, за да може тя да изглежда по един и същи начин, а да работи за различни устройства(принтер плотер и др.). Повечето от изходните устройства са растерни (по пиксели ), но изображението трябва да се съхранява във векторна форма(с формули). Работи се с Device context. То позволява много настройки на атрибутите.



Атрибути на Device contextтова са настройки, които се уточняват еднократно и по подразбиране.

Режим на чертаене - начин на комбиниране на извежданото изображение с текущото

CDC :: SetROP2 (); //Set Raster Operation to

Пр.:

dc.SetROP(R2_NOT );



dc.MoveTo(0,0);

dc.Linto(0,2)


42,Mapping Mode

Избраната mapping mode се помни в текущия DC и може да се прочете GetMapMode() – SetMapMode() ).



Има следните MM:

= ММ позоляващ мащабитане анизотропна, както и различна ориентация на осите.

= ММ, както горната , но с еднакъв мащаб по двете оси (изотропна).

= ММ лог. единица  във физическа 0.001 инч или 0.01 инч. Осите са : надясно и нагоре

= ММ, както горната но с 0.01мм или 0.1 мм.

= ММ, лог. единица е = 1 пиксел (текстова). Осите са надясно и надолу.

= ММ лог. единица се преобразува в 1/20 от точката (1/1440 от инч). Осите са надясно и нагоре.

Има възможност за манипулация на обект чрез координатната мрежа. Може да се упр. транслация, ротация, мащабиране, промяна на ориентацията на осите за определен Device context. Има функции за автоматично увеличение, ротация, транслиране, инверсно изображение, сплескване.



Превръщане на координати

Това става с CDC::LPtoDP() или CDC::DPtoLP();

за да получим в цифров вид централната точка на екрана:

CRect rect; GetClientRect(&rect);

CPoint point( rect.width() / 2, rect.Height() / 2);

Но ако искате същата инф. в MM_LOENGLISH единици:



CRect rect;

GetClientRect(&rect);

CPoint point( rect.width()/ 2, rect.Height()/ 2);

CClientDC(this);

dc.SetMapMode(MM_LOENGLISH);

dc.DPtoLP(&point);



Местене началото на коорд.с-ма

CDC::SetWindowOrg() // за прозореца

CDC::SetViewportOrg() // за видимата област

- клиентски координати;

- екранни координати;

преобразуваме:



CWnd::ClientToScreen(); CWnd::ScreenToClient();

Клиентските координати се задават с началните координати (горния ляв ъгъл на клиентската част).

Екранни координати - координати спрямо горния ляв ъгъл на екрана.

Друг атрибут е областта на извеждане Clipping Region може да се окаже област в клиентската област, в която след избора се извежда информацията.

Базови типове DC:

-Display DC

-Printer DC свързва се с принтер или плотер

-Memory DC свързва се с работа и bitmap

-Информационен DC

MFC класова йерархия за поддръжка на DC в NT

-CDC базов калс

-CPaintDC използва се за прерисуване с Wnd_ms_Paint

-CClientDC използва се за прерисуване извън Wnd_ms_Paint

-CmetaFileDC има възможност за направата на метаблокове

-CWindowDC когато ще рисуваме в дадена област, на прозореца а не само в клиентската

Последователността с MetaFile обикновено протича така:

1.създава се променлива от тип СmetaFile;

2.рисуваме като командите се съхраняват в MetaFile;

3.след като приключим заключваме MetaFile-а;

След това в друг DC с метод, в който се указва MetaFile, може той да се изпълни

За да изработите DC в приложението можете:



CDC* pDC = GetDC(); //всъщност CWnd::GetDC()

/* използване на DC за рисуване */ ReleaseDC(pDC);

същото може и с :

PAINTSTRUCT ps;

CDC* pDC = BeginPaint(&ps);

…..


Извън кл. област трябва друг DC:

CWnd::GetWindowDC();

За да получим инф. за възможностите на у-вото преди рисуване:

CDC::GetDeviceCaps(); //напр. допустими цветове, пиксели…

пр:

CClientDC dc(this);



int cx = dc.GetDeviceCaps(HORZRES);

int cy = dc.GetDeviceCaps(VERTRES);

// получаваме напр. 1024 , 768

43.GDI обекти

Pen -писала чертае линия

Brush - четка (фон,област)

Bitmap Palette

Font шрифт(подр. Solid black)

Region областта,може да е правоъгълна елиптична или многоъгълна,може да се запълва, рисува в нея, да се тества дали курсора на мишката е в областта

Всеки от тях може да се подмени с SelectObject():

CBitmap* pbmOld = dcMem.SelectObject( &bmpHello );

Или:


CBitmap* pbmOld = dcMem.SelectObject( &bmpHello );

Pen(писалки )

Има следните атрибути:

ширина;стил; цвят.

- cosmetic pen

- Geometric pen

* Patern


* шаблон за края на ред: заобленост, с правоъгълен ръб или полусглобка).

* шаблон за пресичане на 2 линии: просто, със заобляне или с отсичане.



45.Програмиране в Internet.

Основни понятия:

Клиент-сървър организация (поне 2 приложения TCP/IP протокол) Transmition Control Protocol / Internet Protocol. Протокола се грижи да синхронизира работата.

1. Задължението му е да се пускат пакети от едната страна и да се приемат от другата.

2. Този слой е отворен за адресиране, групиране. Базира се на няколко основни протокола – IP целта му е да адресира пакета, да го фрагментира ако е нужно и да го събере от другата страна отново.

ARP – Address Resolution Protokol – посочване на пакетите според адреса.

ICMP – Internet Control Message Protocol – занимава се с диагностични функции.

IGMP – Internet Group Management Protocl – урпавление на групирането.

Един IP адрес се регистрира в редица хостове, те служат за пакети към него. Тези хостове образуват group. Тази група е „диполисно” множество. Тези хостове трябва да се регистрират в router – ите.

1.В това ниво се поема “отговорност” за цялата сесия.

TCP – това е протокол, който изисква предварително връзка и гарантира надеждността.

UDP – един към един или един към много. Не изисква установена сесия и не е надежден. Пакетите тук имат по-малко служебна информация. Протокола се управлява със средствата на Visual C.

1.Протоколи

HTTP, FTP – File Transfer Protocol, SMTP – mail, Telnet – терминална емулация, port – освен IP и port – а указва мястото.

DNS


Сървъра прослушва и целта е колкото може по-бързо да обслужва заявката, затова той я прехвърля към специализиран Socket (най-дясната колонка на графиката)

46.IP протоколът

Сам по себе си не дава надеждна връзка. Задачите на IP са да реши проблеми на рутирането и адресирането между два комуникиращи хоста. Datagram се интересуват единствено от получател и дължина (отдясно). Получтелят проверява само контролната сума. Всеки Datagram си има уникален идентификатор в рамките на всеки обмен. Той служи за подпомагане, фрагментиране и асемблиране на пакетите. При преход от мрежа в мрежа става чрез рутер и неговата задача е да фрагментира информацията, за да може да се събере във формата на другата мрежа. Рутерът при фрагментация добавя ID и номер на фрагментацията. Целта е при получаване на пакета от хостта да може да ги деасемблира. Има и поле протокол чрез него при получаване на пакет се указва кум кой протокол да се отнесе за обработка. Има и поле TTL - това е число, което показва след колко рутера трябва да се унищожи Datagram. IP адреса е 32 битово число, което е съставено от две части: 1)21 бита от тях идентифицират мрежата; 2) 8 бита идентифицират компютъра в мрежата;



Втори протокол е User Datagram Protocol – UDP:

TCP е най-често използвания протокол. При него може да се възстанови последователността, ако е разместена или изискваме повторно предаване ако е загубена. TCP е ориентиран към предаване и получаване на поредица от байтове без да се интересува от смисловото съдържание. Портове с дължина до 1024 с фиксирано предназначение от американските стандарти.

PORT 80 свързан е с HTTP; PORT 20 и 21 с FTP

47. Application Interface към TCP/UDP/IP

В MFC има 2 групи: WinSoc и WinNet. WinSoc са от по-ниско ниво. WinNet са за клиент-сървър. Има два базови класа асинхронният сокет и класа Csocket. Методите на асинхронният сокет служат да се преобразува асинхронният поток от данни в синхронна последователност от данни към архива или паметта.



Процедурата за работа със сокети е следната:

1.Конструира се обект CSocket: (сокет е: протокол + адрес, а адрес е: IP + port)

CSocket sockSrve;

или

CSocket sockClient;

2.Създава се SOCKET handle(ako е сървър се указва и порт):

sockSrve.Create(nPort)



или

sockClient.Create();

3.Аko e kлиент –

CAsyncSocket::Connect()

Аko е сървър – CAsyncSocket::Listen()

След получаване заявка – в сървъра CAsyncSocket::Accept()

sockSrve.Listen()

sockClient.Connect(strAddr, nPort)

CSocket sockRecv;

SockSrve.Accept(sockRecv);

4.Създава се CSocketFile обект и се асоциира с CSocket:

CSocketFile file(&sockRecv);

5.Създава се CArchive обект и се асоциира с обекта CSocketFile:

CArchive arIn(&file, CArchive::load);

CArchive arOut(&file, CArchive::store);

6.Използва се CArchive обектите за изпращане и получаване на данните:

arIn >> dwValue

arIn >>dwValue

arOut << dwValue

arOut << dwValue

7.Накрая се разрушават обектите CArchive, CSocket , CSocketFile.

Ето схема на използването на тези обекти:

CAsyncSocket

Обхваща функционалността на WinSock API:

CAsyncSocket mysock;

mysock.Create();

Създаване - има над 20 функции:

Accept - създава връзка със сокета

Bind - асоциира локален адрес със сокета

Connect - прави връзка със съответстващия сокет

Receive; Send; Оverridable; OnAccept

OnAccept - съобщава на прослушващ сокет, че може да accept чакаща заявка за връзка .

OnReceive - notifies a listening socket че има чакаща данна за получаване с Receive

Csocket


CSocketFile

CSocketFile(CSocket* pSocket, …);



48. WinInet

Това е API от по-високо ниво, но работи само за HTTP,FTP, Gopher клиенти, не и за сървъри.

Кодът е в WININET.DLL.

Предимства на WinInet:

1. кеширане;

2. чете записаният в registry proxy сървър и прави достъпа през него;

3. буфрира се вход/изхода;

4. удобен API;

5.изгражда автоматично headers, незабелязано пренасочва повикванията.;

В 16 битова среди няма многонишково програмиране, затова в асинхронен режим в програмата ще има много изчакване.

В 32 битова среди имаме многонишково програмиране. Комуникациите могат да се оформят в отделни нишки, а интерфейса в главна нишка. Това позволява нишките при блокиране да се предаде управлението на друга нишка без да увисва интерфейса. Предимно се работи с WinInet.

Обвивка в MFC класове

CInternetSession – Отнася се за всички видове протоколи.

CStdioFile *OpenURL(pstrURL, незад. параметри);

CHttpConnection

Създаването на този обект става след конструиране на CInternetSession с member ф-цията му – GetHttpConnection(), връщаща connection handle (HINTERNET).

CFtpConnection, CGopherConnection

CInternetFile

CHTTPFile* httpfile = (CHTTPFile*) internetSession.OpenURL(strurl);

ChttpFile – създава се така:

CHttpConnection::OpenFile();

CFtpFileFind, CGopherFileFind

CInternetException



Нотификации за прогреса на Internet сесия: За да се работи с тях се конструира наследник, напр:

class CCallBackInternetSession: public CinternetSession

{

..public: CCallBacknternetSession(…){EnableStatusCallback(..)

}

protected: OnStatusCallback(..)};

като:


  1. В конструктора се вика CInternetSession::EnableStatusCallback(), която разрешава обратните повиквания.

  2. Предефинира се member ф-ията OnStatusCallback(… dwInternalStatus,…)


49. Примерна кл.прогр.за инет.сървър

Ето код на примерна клиентска програма, осъществяваща заявка Get към Internet сървър. Кодът се поставя в отделна нишка. За да стане това името на нишковата проц. да се постави в:



AfxBeginThread(ClientWinInetThreadProc,….);

на главната нишка на приложението.



CString g_strServerName = “Localhost”;

UINT ClientWinInetThreadProc( LPVOID pParam){

CInternetSession session;

CHttpConnection* pConnection = NULL;

CHttpFile* pFile1=NULL;char* buffer=new char[MAXBUFF];

UINT nBytesRead=0;

try{pConnection = session.GetHttpConnection( g_strServerName, 80);

pFile1 = pConnection  OpenRequest( 1, “/”); //сляпо GET

pFile1SendRequest();

nBytesRead = pFile1Read(buffer, MAXBUF – 1);

buffer[nBytesRead] = ‘\0’;

char temp[10];

if(pFile1Read(temp, 10) != 0)

//повторен опит за четене

AfxMessageBox(“Файлът надхвърля размера – файлът не е кеширан”);

}

AfxMessageBox(buffer);

}

catch( CInternetException* e){// обработка на изключението

edelete;}….


51.NET Framework програмна среда и система на управление на общи типове

source FileC++, C#, Eiffel, Python, Visual Basic, Jscript, Fortran,

IL - Езиково-специфичен компилаторC++, C#

Изпълним файлIL Code & Metadata

RuntimeИзпълнима Среда

CLR Type System


Value Types

Reference Types

Built-in Value Types

User-DefinedValue Types

Reference Types

ObjectTypes

Interface Types

User – Defined

Reference Types

Pointer Types



Дефиниция за стойностен тип (наследил System.ValueType) и референтен тип.

заемане пространство от стека и от хийпа

референтните обръщения са силно типизирани.

garbage collector мести обекти в хийп иосъвременява референциите

CLR генерира указатели към user-defined типовете, при необходимост (липсата на връзка)
52 Стойностни типове

1. ВГРАДЕНИ

CIL FCL описние CLS поддръжка

bool System.Boolean true-false Y

char System.Char Unicode character Y

int8 System.SByte signed 8 bits N

int16 System.Int16 signed 16 bits Y

int32 System.Int32 signed 32 bits Y

int64 System.Int64 signed 64 bits Y

unsigned int8System.Byte unsigned 8 bits Y

unsigned int16System.UInt16 unsigned 16 bits N

unsigned int32 System.UInt32 unsigned 32 bits N

unsigned int64 System.UInt64 unsigned 64 bits N

float32 System. Single IEEE 32 bits FP Y

float64 System.Double IEEE 64 bits FP Y

native int System.IntPtr signed native int Y

native unsigned int System.UIntPtr unsigned native int N

2. Булеви

3. characters16 bits Unicode

4. Integers

5. Floating Point types

User-defined Value Types: в стека; липсва default constructor; биват изброими и структури изброими

using System

namespace Enumeration

{ struct EnumerationSample

{ enum Month { January = 1, February,…… }

static int Main(string[] args)

{ Console.WriteLine(“{0} is month {1}”, Month.September, (int) Month.September);

return 0;

}}}


структури (C++  class; C#  struct за value type и class за reference type

53 Типове методи, събития, полета, properties.

В структурите може да се съдържат:

. методи (static or instance)

using System;

namespace ValueTypeMethods

{struct Sample

{ public static void SayHelloType()

{Console.WriteLine(“Hello from type”);}

public void SayHelloInstance()

{ Console.WriteLine(“Hello from instance”);}

static void Main(string[] args)

{ SayHelloType();

Sample s = new Sample()

s.SayHelloInstance();

}}}

fields (static- когато типът няма стойност - or instance). Има тип и име



properties ( static or instance). “Логически полета” с тип

using System;

namespace ValueType

{struct Point

{private int sPosition, yPosition;

public int X

{get {return xPosition;} // генерира се метод get_X

set {xPosition = value;}// генерира метод set_X

}

public int Y



{get {return yPosition;}

set {yPosition = value;}

}}

class EntryPoint



{static void Main(string[] args)

{Point p = new Point();// не в heap, а в стек, защото “p” е value type

p.X = 44; //компилаторът генерира повикване на set_X

p.Y = 55;

Console.WriteLine(“X: {0}”, p.X);

Console.WriteLine(“Y: {0}”, p.Y);

}}}

events ( static or instance). Той има име и тип (сигнатурата на callback методa). След дефиниране на event автомат. се генерират методи add_EventName и remove_eventName за добавяне и премахване на listeners за събитието.



Tип с дефинирани в него събития уведомява други обекти за възникването им.

Други обекти могат да регистрират или отрегистрират интерес към събитието, като го отработят по различен начин.

кратък пример:

using System;

namespace EventSample

{

public delegate void Adelegate();



struct EventClass

{public event ADelegate AnEvent;

public void InvokeEvent()

{

if (AnEvent != null)



AnEvent();

}

static void CallMe()



{Console.WriteLine(“ I got called”);)}

static void Main(string[] args)

{

EventClass e = new EventClass();



e.AnEvent += new ADelegate(CallMe);

e.AnEvent += new ADelegate(CallMe);

e.AnEvent += new ADelegate(CallMe);

e.InvokeEvent();

}}}

54 Проектиране на тип, предлагащ събитие. Проектиране на тип използващ събитие.

Проектиране на тип, предлагащ събитие

class EventManager{

// следва вграден тип, дефиниращ информацията, предавана на

// получателите на събитие

public class MailMsgEventArgs : EventArgs{

public MailMsgEventArgs( String from, String to, String subject, String body)

{ this.from = from; this.to = to; this.subject = subject; this.body = body;}

public readonly String from, to, subject, body;}

// следва делегат, дефиниращ прототип на callback метод, който

// получателите следва да имплементират

public delegate void MailMsgEventHandler ( Object sender, MailMsgEventArgs args);

//дефиниция на самото събитие – от същия тип

public event MailMsgEventHandler MailMsg;

// метод, отговорен за уведомяване на регистриралите интерес към събитието обекти

protected virtual void OnMailMsg(MailMsgEventArgs e)

{ if(MailMsg != null) //има ли регистрирали интерес към събитието

{MailMsg( this. e); //уведомяваме всички рег. обекти

}}

// метод, получаващ от вход данни и ги превежда (възбужда) събитието



public void SimulateArrivingMsg(String from, String to, String subject, String body)

{MailMsgEventArgs e = new MailMsgEventArgs(from, to, subject, body);

//вика метода уведомяващ обектите за събитието

OnMailMsg(e);

}}

Всъщност дефиниране на : public event MailMsgEventHandler MailMsg; се преобразува от компилатора така:



* създава се private делегатно поле, в началото null, впоследствие поддържащо референция към свързан списък от делегати, желаещи да бъдат уведомявани за събитието.

* дефинира public void add_MailMsg(MailMsgEventHandler handler) метод, добавящ референция в свързания списък.

* дефинира public void remove_MailMsg(MailMsgEventHandler handler) метод, отрегистриращ event handler за обект, който вече не се интересува от събитието.

Към методите от 2. и 3. са добавени атрибути за синнхронизация т.е. те са нишково обезопасени и много слушатели могат да работят едновременно с тях.

Методите са public, защото и съзитието е било декларирано public

Б. проектиране на тип, слушащ за събитие

class Object1 {

// предаване на EventManager към конструктора

public Object1(EventManager mm)

{// добавяме референция към слушателя (FaxMsg callback метода) към MailMsg списъка на

// EventManager

mm.MailMsg += new EventManager.MailMsgEventHandler(FaxMsg);

// конструира се делегатен обект, обвиващ метода FaxMsg в интерфейс за да може да бъде

// външно повикан с Invoke() – вж. делегати) }

// следва описание на callback метода , който EventManager ще извика при събитие

private void FaxMsg( Object sender, EventManager.MailMsgEventArgs e)

{…………………………….}

public void Unregister( EventManager mm)

{// конструирваме инстанция на MailMsgEventHandler делегата, рефериращ callback метода

// FaxMsg и го отрегистрирваме като елемент от списъка

EventManager.MailMsgEventHandler callback_element = new EventManager.MailMsgEventHandler(FaxMsg);

mm.MailMsg -= callback_element;

}}

Sealed Value Type

* value type не се наследява

* sealed

55 Пакетирани типове(boxed types)

възможни за всеки value type, вкл. user-defined, автоматично се генерират в обвиващ обект (boxing).

unboxing – връща value type в норм. състояние. Изработва указател към данната (до момента съдържана в boxed обект), копира данните на boxed обекта във value type и в стек. Помества boxed обекта в heap следователно всеки value type, може да се разглежда като обект, при необходимост и да взаимодейства с всеки друг обект (всички са наследници на Object). Общото наследство наподобява IUnknown.

Всеки box type поддържа интерфейси

using System;

struct Point

{public Int32 x,y;

public void Change(Int32 x, Int32 y) { this.x = x; this.y = y; }

public override String ToString()

{ return Strinf.Format( “{0}, {1}”, x, y);}}

class App

{ static void Main()

{

Point p = new Point();



p.x = p.y = 1;

Console.WriteLine(p);// (1,1)

p.Change(2, 2);

Console.WriteLine(p);// (2, 2)

Object o = p;// boxing

Console.WriteLine( о );(2, 2)

(( Point) o).Change(3, 3);

// защото Change() е метод на Point

// “ о “ се разопакова. Полетата му се копират във value type Point в стека и се променят на 3

Console.WriteLine( o );// (2, 2) – това е “пакетираният” обект



56 Референтни типове

Reference Types

* комбинира инф. за местоположение и за съдържание.

* местоположението е “Type Safe”, т.е. само assignment-compatible типове могат да се пазят там.

* garbage collector мести тези обекти свободно.

А. Object Types

Наследяват Object (System.Object).

Основни методи: Equals; Finalize (вика се преди gc да освободи паметта); GetType (важно е че методът е невиртуален – т.е. не е възможно някой да се представи за друг);

MemberwiseClone; ToString.

using System;

namespace Override

{

class Sample



{ static void Print( params Object[] objects)

{ foreach(Object o in objects)

Console.WriteLine( o.ToString());

// вика подходящие метод за всеки аргумент, ако съществува }

static void Main( string[] args)

{

Object o = new Object();



String s = “Nakov”;

int I = 33;

Print( o,s, i); // int boxed element

}}}


Предаване променлив брой параметри:

static Int32 Add(params Int32[] values )

{

Int32 sum = 0;



for( Int32 x = 0; x< valies.Lenght; x++)

sum += values[x];

return sum; }

Викаме го така: Add( 1,2,3,4,5,6)

което е по-нагледно от:

Add(new Int32[] { 1,2,3,4,5,6})

* ключовата дума params добавя атрибут към параметъра [ParamArray].

* Компилаторът претърсва за съответстващи методи без params и след това за такива с params. Тогава пакетира параметрите в масив и вика метода с указател към масива.

* само последният параметър на метод може да е с params

* данните трябва да могат да се пакетират в едномерен масив

* метод с променлив брой параметри от различен тип се декларира:

Method ( params Object[] objects)

Важен CLR вграден тип (освен Object) е String

* той е sealed

* всеки метод, модифициращ низ, създава нов низ

* основни методи:

конструктори ( няма default) за различни аргументи – char, масив char, указат. към char

Compare; Concatenate; Format; IndexOf; Insert; Length….

using System;

namespace StringSample

{

class Sample



{

static void Main(string[] args)

{ String s = “Nakov”; // без new (може, защото е вграден)

Console.WriteLine(“Length is:” + s.Lenght); // вземаме property – дължина

// преобразъва се в boxed тип. String + Object ?

// съществува overrided concatenation method на class String с параметър Object. Console.WriteLine(s.ToLower()); // създава се временен string object

}}}

57 Интерфейсни типове

Interface Types

* въведени в COM и CORBA

* целта е не само функционална наследяемост. но и поделяне на общ външен вид – интерфейс

* интерфейсният тип е частична спецификация на тип

* поддържа се наследяемост на интерфейсни типове

* интерфейсният тип съдържа:

- методи (статични и на инстанция);

- полета (статични);

Property - - events

Методите на интерфейс са public, abstract virtual.

Base Framework ( а не CLR) поддържа множество интерфейсни типове

using System;

using System.Collection;

namespace StringSrray

{class EntryPoint

{static void Main(string[] args)

{String [] names = {“ Nakov”, Angelov”, Najdenov”};

// автоматично се създава array type , имплементиращ IEnumerator

// типът поддържа редица методи: Clear(); GetLenght(); Sort()IsSynchronized(), SyncRoot()…

// Sort() използва IComparable, който следва да е реализиран от array типа ни

IEnumerator I = names.GetEnumerator();

while(i.MoveNext())

Console.WriteLine(i.Current);

}}}

В. Pointer type

unmanaged function pointer

managed pointers

unmanaged pointer referring values



Г. User- Defined Object Type

using System;

namespace ObjectType

{ public delegate void ADelegate();

public interface IChanged

{ event ADelegate AnEvent; }

public interface IPoint

{

int X { get; set}



int Y {get; set;}

}

class Point: IChanged, IPoint



private int xPosition, y{Position;

public event ADelegate AnEvent;

public int X

{ get { return xPosition;}

set { xPosition = value; AnEvent();} }

public int Y

{

get {return xPosition;}



set { yPosition = value; AnEvent();}

}

class EntryPoint



{

static void CallMe()// делегат

{ Console.WriteLine(“ I got called”)’}

static void Main (string [] args)

{ Point p = new Point();

IChanged is = p;

IPoint ip = p;

ic.AnEvent == new ADelegate(CallMe);

ip.X = 44; // интерфейсът вика само своите методи;

ip.Y = 55;

Console.WriteLine(“X: {0} Y: {1}”, p.X, p.Y);

}}}


Д. Интерфейси и Value типове

using System;

namespace InterfaceSample

{public delegate void Changed();

interface IPoint

{ int X


{ get; set;}

int Y


{ get; set;}

}

struct Point : IPoint // value type , наследил интерфейс



{ private int xValue, yValue;

public int X

{ get { return xValue;}

set { xValue = value;}

}

public int Y



{ get { return yValue;}

set { yValue = value;}

}

}

public class EntryPoint



{ public static int Main()

{

Point p = new Point();



p.X = p.Y = 33;

IPoint ip = p; // interface pointer – в heap, value типа в стека

Console.WriteLine(“X: {0}, Y: {1}”, ip.X, ip.Y);

// ip има достъп само до reference типове, докато p е value type. Следователно p е опакован и

// ip има достъп до опакования обект и членове.

}

}}



Присвояване и съвместимост при съвпадение на типовете - когато присвоявания обект е от подтип;

когато имат общ интерфейс .

using System;

namespace AssignmentCompability

{

class Sample



{static void Main(string[] args)

{System.Int32 I = 42;

Object o;

String s = “Nakov”;

IComparable ic;

o = s; //OK

ic = s ;//OK – обект s поддържа IComparable

o = i; //OK влиза в box и се присвоява към обект

ic = i; // OK i се пакетира

i = s; // грешка при компилация

s = (String) o;

// runtime error: в момента “о” съдържа i . Свива се обсега на boxed обект към подобект

} }}
58 Делегати

Делегати
- callback функции в Windows

- callback функции, реализиращи специфични обработки: qsort от runtime библиотеката приема callback ф-ия , сортираща елементите на масив

- callback не носи инф. за брой и тип параметри, връщана стойност, конвенция на повикване.

- callback функциите не са типово-обезопасени

- .NET и делегатите

using System;

using Syste.Windows.Forms;

using System.IO;

class Set

{private Object[] items;

public Set(Int32 numItems)

{ items = new Object[numItems];

for( Int32 i = 0; i< numItems; i++) items[i] = i;}

public delegate void Feedback( Object value, Int32 item, Int32 numItems);

// декларира се публично делегат и се описва сигнатурата му

public void ProcessItems(Feedback feedback) // делегират се обработките към

// feedback

{ for( Int32 item = 0; item

{if(feedback != null)
{ feedback(items[item], item+1; item.Lenght); }

/ / ако има callback ф-ии, те се извикват за всеки обект


}}}

class App


{ static void Main()

{StaticCallbacks();

InstanceCallbacks()

}

static void StaticCallbacks()


Set setOfItems = new Set(5);

setOfItems.ProcessItems(null);

setOfItems.ProcessItems( new Set.Feedback(App.FeedbackToConsole));

setOfItems.ProcessItems( new Set.Feedback(App.FeedbackToMsgBox));

Set.Feedback fb = null;
fb += new Set.Feedback(App.FeedbackToConsole);
fb += new Set.Feedback(App.FeedbackToMsgBox);
setOfItems.ProcessItems(fb);
}

static void FeedbackToConsole( Object value, Int32 item, Int32 numItems)

{ ………………}

static void FeedbackToMsgBox( Object value, Int32 item, Int32 numItems)

{ ……………...}

}

static void InstanceCallbacks() {


Set setOfItems = new Set(5);
App appobj = new App();
setOfItems.ProcessItems( new Set.Feedback(appobj.FeedbackToFile)); }
void FeedbackToFile( Object value, Int32 item, Int32 numItems_
{ ……………}

Дефинират се с кл. дума delegate

конструират се техни инстанции с new

вика се callback метода, като вместо име на метод, подаваме променлива, реферираща делегатен обект



как CLR и компилаторът осигъряват поддръжката за делегати:
нека имаме:
public delegate void Feedback( Object value, Int32 item, Int32 numItems);
Компилаторът дефинира клас за делегата:
public class Feedback : System.MulticastDelegate
{public Feedback( Object target, Int32 methodPtr); // конструктор
public void virtual Invoke( Object value, Int32 item, Int32 numItems);
// методът има същият прототип като делегата;

public virtual IAsyncResult BeginInvoke( Object value, Int32 item, Int32 numItems,AsyncCallback callback, Object object);


public virtual void EndInvoke(IAsyncResulet result);

}

делегатният обект е обвивка около метод и обект , с който методът работи



Обрущението към callback метод е като с ф-ия. Всъщност това е променлива , реферираща делегатен обект. Компилаторът извиква Invoke(). Все едно:

feedback.Invoke( items[item], item, items.Lenght);

Invoke() може да се вика явно от други езици

Обсег на член на тип

public

assembly


Family

Family or assembly

Family and Assembly

Compiler-controlled

Private

44. Шрифт :

- font pitch – широчината на буквата. Има fixed pitch, variable pitch;

-Serif –завършека на буквата: Serif sans serif; - raster fonts; - vector fonts; - TrueType fonts. Фамилии шрифтове: - decorative; - modern; - roman; - script;- swiss.

Атрибути на шрифт: височина в лог. единици; character set: ANSI_CHARSET; OEM_CHARSET; SYMBOL_CHARSET .

- output precision; clipping region ; output quality;

- фамилия: FF_DECORATIVE; FF_DONTCARE; FF_MODERN; FF_ROMAN; FF_SCRIPT; FF_SWISS.

- плътност (font weight); escapment; orientation; Italic, underline, strikethrough; Typeface



Избор на шрифт в програма:

Void CDCTestView::OnDraw(CDC* pDC)

{CRect rcClient;

GetClientRect( rcClient; pDCàDPtoLP ( rcClient);

COLORREF clrold = pDCàSetTextColer( RGB(0,255,0));

int oldMode = pDCàSetBkMode (TRANSPARENT);

CFont fntArial; fntArial.CreateFont(0,0,0,, “Arial”);

CString szMsg = “I’m writing with Arial”;

CFont* pOldFont = pDCàSelectObject( &fntArial);

pDCàTextOut(……………., szMsg); pDCàSelectObject( pOldFont); ...



Bitmaps - Device Independent Bitmap (DIB); Device Dependent Bitmap (DDB). Ето пример за изобразяване на битмап с ресурсен ID – IDB_HELLO в view ( в OnDraw()):

void CBitmapView::OnDraw( CDC* pDC) {CBitmap bmp; Bmp.LoadBitmap (IDB_HELLO ) ; //определяне размера на битмап BITMAP bm; Bmp.GetObject( sizeof(BITMAP), &bm);

// създаваме memory DC, селектираме битмап в него и извеждаме към екран CDC dcMem; DcMem.CreateCompatibleDC(pDC);

CBitmap* pbmOld = dcMem.SelectObject( &bmp);

PDcàBitBlt(10,10,bm.bmWidth, bm.bmHeight, &dcMem, 0,0SRCCOPY);

7. Съобщения и карта на съобщения:


On_MESSAGE(WM_MYMESSAGE, OnMyMessage) afx_msg LPRESULT;

OnMyMessage(WPARAM wParam, LPARAM lParam);

message map структури:

_messageEntries масиви member ф-ии

CWnd

&CcmdTarget::messageMap &CWnd::_messageEntries[0]



WM_DRAWITEM CWnd::OnDrawItem ….

CframeWnd

&CWnd::MessageMap &CFrameWnd::_messageEntries[0] WM_MENUSELECT CFrameWnd::OnMenuSelect

WM_CREATE

CFrameWnd::OnCreate

WM_DESTROY

CFrameWnd::OnDestroy ChelloWnd ….

&CFrameWnd::messageMap &CHelloWnd::_messageEntries[0] WM_PAINT CHelloWnd::OnPaint

Кодови таблици и макрос _Т : “Hello”-ANSI; L”Hello” – Unicode; _T(“Hello”) - според директива #define _UNICODE

забележка: 1. декларации TCHAR вместо char; 2. TCHAR*или LPTSTR или LPCTSTR вместо char* ; 3.дължината на знак е sizeof(TCHAR); 4. вместо стандартни run-time ф-ии: strcopy() tcscpy() или tcscat().









Сподели с приятели:
1   2   3   4




©obuch.info 2024
отнасят до администрацията

    Начална страница