vizual programchilal cu lekts

58
Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй Боловсруулсан багш: Т.Уламбаяр Page 1 Visual C++) Lecture 1-2 Виндоуз орчинд Визуаль С++ хэл ашиглан программ бичих Microsoft Visual C++ Microsoft Visual C++ нь С болон С++ хэл дээр төрөл бүрийн программ бичихэд зориулагдсан. Өөрөөр хэлбэл Windows орчны программыг С++ хэлийг ашиглан бичихэд зориулагдсан. Мөн MFC (Microsoft Founded Classes) –г ашиглан өөрийн программын хүчин чадлыг нэмэгдүүлэх боломж олгодог Визуаль Программчлалын Орчин юм. Визуаль С++ нь таны программ бичих бүх алхмуудыг (бичиглэл нэмэх, хөрвүүлэх, ажиллуулах, ажиллагааг шалгах, программыг оновчтой болгох) хянаж чиглүүлж өгнө. Visual C++ -г ажиллуулахдаа дараах алхмуудыг гүйцэтгэнэ. 1. Windows –н Start цэсний Programs дэд цэсийг сонгоно. 2. Microsoft Visual C++ 6.0 –г сонго. (хэрэв та Visual C++-н зөвхөн дангаараа байдаг хэлбэрийг суулгасан бол Microsoft Visual C++ 6.0 -г, Microsoft Visual Studio -н нэгэн хэсэг болдог хэлбэрийг суулгасан бол Microsoft Visual Studio 6.0 -г сонгож доторхи жагсаалтаас Visual C++-г сонгоно) 3. Дээрхи цонх нь танд Visual C++-г ашиглах бяцхан заавруудыг өгнө. Next Tip товчийг даран дараагийн зааврууд руу орж болно. Close товчийг дарж ажилдаа орно. Visual C++ хэл дээр бичигдэж байгаа программын зүрхэн хэсгийг Ажлын зайд (WorkSpace) агуулагдах прожект (project) гэж хэлж болно. Нэг ажлын зайд хэд хэдэн прожект байж болно. Жишээ нь хэрэв та DLL (Dynamic Link Library) файл бичиж байгаа бол түүний ажиллагааг шалгах программыг тухайн ажлын зайд үүсгэж болно. Прожект файл нь .dsp (developer studio project) өргөтгөлтэй байх ба үүнд программд хамаарах файлууд тухай мэдээллийг агуулахаад гадна Visual C++ программыг хэрхэн ажиллуулах, хөрвүүлэх талын тохируулгуудыг мөн агуулна. Прожект файл үүсгэх болгонд ажлын зай үүсэх ба .dsw (developer studio workspace) өргөтгөлтэй байна. Үүнд Visual C++ -н аль цонх харагдаж аль нь харагдахгүй байгаа зэрэг мэдээллүүдийг агуулна. WorkSpace нь программын кодыг 3 хэлбэрээр харуулна. 1. Class View программын кодыг С++ хэлний обьект (class) –н түвшингээр харуулна. Мод хэлбэрээр харуулах ба обьектуудыг гишүүн өгөгдөл, гишүүн функцийг харуулна. 2. Resource View программын төрөл бүрийн санг (цонх, цэс, зураг) харуулах ба засвар хийх боломжийг олгоно. 3. File View программын бүх файлуудыг харуулна. Прожектийн тохируулгыг Project цэсний Settings командыг WorkSpace –ийн тохируулгыг Tools цэсний Options болон Customize командуудыг сонгосноор хийж болно. Шинээр прожект үүсгэх Анхны программ Энэ программ нь 2 товчтой цонх ба эхний товчийг дарахад Hello гэсэн мэдээлэл гарч ирдэг, удаах товчийг дарахад программаас гардаг. Шинээр прожект үүсгэхийн тулд дараах алхмуудыг гүйцэтгэнэ. 1. Шинээр прожектийн ажлын зай үүсгэнэ. 2. Application Wizard-г ашиглан программын код болон санг үүсгэнэ. 3. Үүссэн санд буй цонхны харагдах байдлыг өөрийн үзэмжээр өөрчлөнө. 4. Кодод Hello мэдээлэл гаргах үйлдлийг нэмнэ. 5. Программын зургийг (icon) солино. Шинээр прожектийн ажлын зай үүсгэх. 1. File цэсээс New командыг сонгоно.

Upload: e-gazarchin-online-university

Post on 19-Jul-2015

111 views

Category:

Documents


9 download

TRANSCRIPT

Page 1: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 1 

Visual C++) Lecture №1-2 Виндоуз орчинд Визуаль С++ хэл ашиглан программ бичих

Microsoft Visual C++ Microsoft Visual C++ нь С болон С++ хэл дээр төрөл бүрийн программ бичихэд зориулагдсан. Өөрөөр хэлбэл Windows орчны программыг С++ хэлийг ашиглан бичихэд зориулагдсан. Мөн MFC (Microsoft Founded Classes) –г ашиглан өөрийн программын хүчин чадлыг нэмэгдүүлэх боломж олгодог Визуаль Программчлалын Орчин юм. Визуаль С++ нь таны программ бичих бүх алхмуудыг (бичиглэл нэмэх, хөрвүүлэх, ажиллуулах, ажиллагааг шалгах, программыг оновчтой болгох) хянаж чиглүүлж өгнө. Visual C++ -г ажиллуулахдаа дараах алхмуудыг гүйцэтгэнэ.

1. Windows –н Start цэсний Programs дэд цэсийг сонгоно. 2. Microsoft Visual C++ 6.0 –г сонго. (хэрэв та Visual C++-н зөвхөн дангаараа байдаг

хэлбэрийг суулгасан бол Microsoft Visual C++ 6.0 -г, Microsoft Visual Studio -н нэгэн хэсэг болдог хэлбэрийг суулгасан бол Microsoft Visual Studio 6.0 -г сонгож доторхи жагсаалтаас Visual C++-г сонгоно)

3. Дээрхи цонх нь танд Visual C++-г ашиглах бяцхан заавруудыг өгнө. Next Tip товчийг

даран дараагийн зааврууд руу орж болно. Close товчийг дарж ажилдаа орно. Visual C++ хэл дээр бичигдэж байгаа программын зүрхэн хэсгийг Ажлын зайд (WorkSpace) агуулагдах прожект (project) гэж хэлж болно. Нэг ажлын зайд хэд хэдэн прожект байж болно. Жишээ нь хэрэв та DLL (Dynamic Link Library) файл бичиж байгаа бол түүний ажиллагааг шалгах программыг тухайн ажлын зайд үүсгэж болно. Прожект файл нь .dsp (developer studio project) өргөтгөлтэй байх ба үүнд программд хамаарах файлууд тухай мэдээллийг агуулахаад гадна Visual C++ программыг хэрхэн ажиллуулах, хөрвүүлэх талын тохируулгуудыг мөн агуулна. Прожект файл үүсгэх болгонд ажлын зай үүсэх ба .dsw (developer studio workspace) өргөтгөлтэй байна. Үүнд Visual C++ -н аль цонх харагдаж аль нь харагдахгүй байгаа зэрэг мэдээллүүдийг агуулна. WorkSpace нь программын кодыг 3 хэлбэрээр харуулна.

1. Class View программын кодыг С++ хэлний обьект (class) –н түвшингээр харуулна. Мод хэлбэрээр харуулах ба обьектуудыг гишүүн өгөгдөл, гишүүн функцийг харуулна.

2. Resource View программын төрөл бүрийн санг (цонх, цэс, зураг) харуулах ба засвар хийх боломжийг олгоно.

3. File View программын бүх файлуудыг харуулна. • Прожектийн тохируулгыг Project цэсний Settings командыг • WorkSpace –ийн тохируулгыг Tools цэсний Options болон Customize командуудыг

сонгосноор хийж болно. Шинээр прожект үүсгэх Анхны программ

Энэ программ нь 2 товчтой цонх ба эхний товчийг дарахад Hello гэсэн мэдээлэл гарч ирдэг, удаах товчийг дарахад программаас гардаг. Шинээр прожект үүсгэхийн тулд дараах алхмуудыг гүйцэтгэнэ.

1. Шинээр прожектийн ажлын зай үүсгэнэ. 2. Application Wizard-г ашиглан программын код болон санг үүсгэнэ. 3. Үүссэн санд буй цонхны харагдах байдлыг өөрийн үзэмжээр өөрчлөнө. 4. Кодод Hello мэдээлэл гаргах үйлдлийг нэмнэ. 5. Программын зургийг (icon) солино.

Шинээр прожектийн ажлын зай үүсгэх. 1. File цэсээс New командыг сонгоно.

Page 2: Vizual programchilal cu lekts

Визу

Бол

уал програ

о

ПрогПрог

амчлал СИ

овсруулсан

2. P3. P4. L5. O

AAppWizaгүйцэтгэн

123

4

567

8

91

граммын цораммын хар

1. Reso2. Dialo

хара3. TODO4. Canc

хэмж

5. ХулгаPrope

6. Гарч цонх

И++ хичээл

н багш: Т.

Projects хэсгэProject NameLocation хэсэOk товчийг AppWizard-г ard-г ашиглнэ. . Алхам 1-

2. Алхам 2-3. Програм

Applicatio4. Алхам 3

алхамд ш5. Finish то6. Ok товчи7. Програм

Хөрвүүлэ8. Хөрвүүлэ

анхааруу9. Build цэс

0. Таны пргэсэн 2 т

онхны харарагдах байдлource View хэog –г дэлгэхэгдах байдалO мэдээллиcel товчийг зжээгээр өөрч

аны баруун erties команирэх цонхныг хаа. Энэ

лийн лекц

.Уламбаяр

ээс MFC Ape хэсэгт прожэгт прожектидар. Ингэхээхлүүлнэ. лан програ

-д Dialog Ba-д ActiveX Cмын нэр биon гэж бичээ

3-д өөрчлөлшилжинэ. вчийг дарахийг дарж пром үүссэнийэлт хийж баэлт хийж улгын тоог хсээс Executeрограмм нэгтовч байна. Аагдах байдллыг дараах эсгийг сонгоэд гарч ирэхл гарч ирнэ.ийг тэмдэглэзөөж цонхнычил.

товчийг Canдыг сонго. ы Caption хэгарч ирэх ц

ийн хураа

р

ppWizard (exжектийн нэрийн байрлахэд 2 үйлдэл

ммын код

sed ApplicatControls тэмдчих хэсэгт бэд Next товчт хийлгүй х

хад үүсэх программын кой дараа Buiайх явцыг Ouдууссаны

харуулна. e Hello.exe ког цонхтой бАль нэг товчлыг өөрчлөбайдлаар өо х IDD_HELLO

ээд устга. (deы дээр авчир

ncel товчин

эсэгт буй утцонхон дээр

ангуй

xe)-г сонго. рийг (Hello) бх замыг заажл хийгдэнэ:

болон са

tion-г сонго. дэглэгээг арибайгаа Helloч дар. хэвээр үлдэ

рограммын тод болон саild цэсээс Butput цонхнодараа про

омандыг сона түүн дээрчийг даран пөх өөрчилье. Үү

O_DIALOG н

el товч) рах ба өргөн

дээр даран

гыг &Close бтухайн товч

бич. ж өгнө. : прожектий

нг үүсгэхдэ

Next товчийилга.

o үгийг арил

ээгээд Next

талаар мэдэнг үүсгэнэ. Build Hello.eоос харж болограммд ба

нгон програр TODO мэпрограммыг

үний тулд

нэрэн дээр 2

нийг нь цонх

гарч ирэх ц

болгон өөрчч буюу контр

йн директоррыг үүсгэнэ..

ээ дараах алхмуудыгг

йг дар.

лган My Firstt Visual C+++

товч дарж төгсгөлийнн

ээлэл гарч ирнэ.

exe командылно.

ыг сонгоно..

айгаа алдаа болонн

ммаа ажиллэдээлэл ба г дуусгана.

луулна. OK, Cancell

2 товшиход цонхны

хны өргөний

цэсээс (Popuup menu)

члөөд Ok товролын шинж

Page 2

вчийг дарж ж чанарууд

Page 3: Vizual programchilal cu lekts

Визу

Бол

уал програ

о

ПрогбайнПрогПрог

Прогүүний

Даал

  

амчлал СИ

овсруулсан

гарч ID хэболо

7. Ok то&Hel

8. Программын това. граммд үйлраммд үйлд

1. HelloClass

2. Даранэмэ

3. Messнэмэ

4. Нэмс5. Өөрч

// TOгэсэн

6. Messгэсэн

7. Программын зурйг солих ша

1. Reso2. Дэлгэ3. Прог

хийснхэлбэ

лгавар: 1. Abou2. Үндс3. Hello

болго4. Mess

И++ хичээл

н багш: Т.

ирэх ба тэдэсэгт контролохгүй. овчийг зурагlo болгон өө

раммаа хөрвчуудыг дара

лдэл нэмэх длийг нэмэхдo товчинд үйs Wizard комаах цонх гарэх обьектийн

sages хэсгэээх эсэхийг ассний дараа Eчлөлт хийхдэDO: Add youн үйдлийн даsageBox("Heн мөрийг нэмраммын ажиргийг солих. ардлагатай

ource View ->эцэнд гарч ираммаа ажинээр програэрийг харж

ut цонхон дэээн цонхны M

o ба Bye хэмон өөрчил. sageBox фун

лийн лекц

.Уламбаяр

дгээрийг пролын нэрийг

гт харагдах өрчил.

рвүүлэн ажилахад Close т

дээ Visual Cйлдэл нэмэхдмандыг сонгоч ирэх ба үүн ID (IDHELL

эс BN_CLICKсуух ба Ok тEdit Code тоээ ur control notараа өөрийнello. This is mм. иллагааг шаAppWizard н. Үүний тулд> Icon -> IDRирэх зураг зиллуулахад аммын тухайболно.

эр Bye хэмэMinimize болмээн мэдээлэ

нкцийг судла

ийн хураа

р

граммист өөбичих ба эн

байдлаар ө

ллагааг нь штовч програ

C++ Class Wiдээ товчин доно. үнд дээр обьLO)–г сонгон

KED –г сонготовчийг дараовчийг даран

tification hanн үйлдлүүди

my first Visua

алга. нь программд R_MAINFRAурах хэрэгслөөрчилсөн зй мэдээллий

ээн мэдээлэлон Maximizeэл гаргадаг

ан гарч ирэх

ангуй

өрийн сонирнэ нэр нь өөр

өрчлөөд ID

шалга. ммыг хааж H

izard-г ашиглдээр баруун

ьектуудын IDно.

оод Add Funан функцийгн тухайн фу

ndler code heийг нэмнэ. al C++ Applic

мын зургийг

ME-р дээр 2лүүдийн ашзураг харагдйг гаргах цон

л гаргадаг тe товчнуудыцонхны HEL

х товч болон

рхлын дагуур контролын

утгыг IDHEL

Hello товч п

лана. н товчийг да

D (Object ID

nction товчийг нэмнэ. ункцэд өөрчл

ere

cation!");

автоматаар

2 товшилт хишиглан зургидах ба Abouнхон дээрээ

товч нэм. ыг гарга. LLO нэрийг

н зургийг өө

у өөрчилж бон нэртэй дав

олно. Үүний вхцаж

LLO, captionn утгыг

рограммыг ххаахгүй

аран гарч иррэх цэсээс

s)-с өөрийн үйлдэл

йг дарна. Эннэ функц

лөлт хийнэ.

р (MFC) үүсггэдэг ба

ий. йг өөрчил.

ut Hello сонгос зургийн то

олтыг ом

My First Appplication

өрчил.

Page 33 

Page 4: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 4 

Lecture № 3-4 Өөрийн программд стандарт контролуудыг ашиглах

Виндовс орчны бүх программуудад (buttons, check boxes, text fields, and drop-down list boxes) зэрэг контролуудыг ашигласан байдаг. Эдгээрийн системээс авч ашигладаг ба бэлэн үүссэн байдаг. Үүнийг Визуаль С хэл дээр авч ашиглах нь маш хялбар байдаг. Бидний өнөөдөр сурах зүйлс:

• Хувьсагчуудыг хэрхэн зарлах ба тэдгээрийг хэрхэн контролуудад хавсаргах • Контрол ба хувьсагчуудын утгыг хэрхэн хооронд нь зохицуулах • Контролуудын ажиллагаанд хэрхэн үйлдэл оруулах • Программын ажиллагааны явцад контролуудын төлөв байдлыг хэрхэн программчлах

Үндсэн контролууд Виндоузын стандарт контролуудад олон төрлийн контролууд байдаг боловч өнөөдөр бид дараах контролуудыг үзнэ:

• Static text • Edit box • Command button • Check box • Radio button • Drop-down list box (combo box)

Эдгээр нь визуаль С++-д бэлэн байдаг бөгөөд шууд авч ашиглах боломжтой. Тэдгээрийг визуаль С –н Dialog Painter-с авч болно. Зураг 1. Static Text Control Үүнийг хэрэглэгчид контролын нэр болон элдэв тайлбарыг текст байдлаар харуулахад ашиглана. Хэрэглэгч ажиллагааны явцад текстийг нь өөрчлөх боломжгүй. Гэвч үүний текстийг программист программын аргаар өөрчилж болно. Edit Box Control Энэ нь хэрэглэгч текст бичих ба текстийг өөрчлөх зориулалттай. Өөрөөр хэлбэл энэ нь программд хэрэгтэй өгөгдлийг хэрэглэгчээс оруулахад ашиглагддаг үндсэн контрол. Гэхдээ энэ нь зөвхөн ердийн текстийг өруулахыг зөвшөөрдөг. Command Button Control Энэ нь хэрэглэгч ямар нэгэн үйлдлийг хийх команд өгөхөд ашиглагддаг. Командын товч контрол нь нэртэй байх ба зарим тохиолдолд зураг байж болно. Check Box Control Энэ нь ямар нэгэн утга үнэн, худал (сонгогдсон эсвэл сонгогдоогүй) гэсэн утга илэрхийлэх үед ашиглагддаг. Radio Button Control Энэ нь Vheck Box-той адил боловч бүлэг байдлаар хэрэглэгддэг буюу олон элементээс аль нэг нь сонгогдсон гэсэн утга илэрхийлдэг. Drop-Down List Box Control Drop-down list box эсвэл combo control нь олон мөр төрлийн жагсаалтаас аль нэгийг нь эсвэл хэд хэдийг сонгосон гэсэн утга илэрхийлдэг.

Одоо дээрх контролуудыг программд хэрхэн ашиглах талаар жишээ авч үзье. Доорхи жишээ нь контролуудын утгыг хэрхэн программд ашиглах, контролуудын төлөв байдлыг хэрхэн өөрчлөх, мөн нэг программаас өөр программыг хэрхэн дуудаж ажиллуулах зэрэг талаар ойлголт өгнө. Үүний тулд

1. Dialog Based, MFC EXE Application шинээр үүсгэнэ. Өмнөх лабораторид үзсэн шиг. Прожектийн нэрийг Day2 гэж өгнө.

2. Контролуудыг цонхон дээр байрлуулна. Object Property Setting Static Text ID IDC_STATIC

Caption This is an example of a Visual C++ Application using a number of controls.

Static Text ID IDC_STATICMSG

Page 5: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан   Page 5 

Caption Enter a &Message: Static Text ID IDC_STATICPGM Caption Run a &Program: Edit Box ID IDC_MSG Button ID IDC_SHWMSG Caption &Show Message Button ID IDC_DFLTMSG Caption &Default Message Button ID IDC_CLRMSG Caption &Clear Message Button ID IDC_RUNPGM Caption &Run Program Button ID IDC_EXIT Caption E&xit Combo Box ID IDC_PROGTORUN Group Box ID IDC_STATIC Caption Enable Actions Group Box ID IDC_STATIC Caption Show Actions Check Box ID IDC_CKENBLMSG Caption &Enable Message Action Check Box ID IDC_CKENBLPGM Caption E&nable Program Action Check Box ID IDC_CKSHWMSG Caption S&how Message Action Check Box ID IDC_CKSHWPGM Caption Sh&ow Program Action

Мөн Tab товчоор шилжих дарааллыг тодорхойлно. (Layout цэсний Tab Order команд)

Combo Box-н төрийн жагсаалтанд утгыг дараах байдлаар нэмнэ. Шинэ мөр нэмэхдээ

багш: Т.Уламбаяр

Page 6: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 6 

ctrl+Enter товчнуудыг хамт дарна. 3. Контролуудад хувьсагч хавсаргана. Визуаль С++ д контролуудыг хувьсагчтай

хамтруулж ашигладаг өөрөөр хэлбэл контрол дахь утгыг хавсаргасан хувьсагчаар дамжуулан программд ашиглах мөн контролын текстийг хувьсагчаар дамжуулан өөрчлөх зэрэг үйлдлийг хийхэд ашиглана. Үүний тулд UpdateData(boolean arg) функцыг ашигладаг. Энэ функцын arg аргументад TRUE утга өгвөл контролоос утга авах, FALSE утга өгвөл контолын утгыг хавсаргасан хувьсагчийн нь утгаар өөрчлөх үйлдлийн гүйцэтгэнэ. Контролуудад хувьсагч хавсаргахын тулд дараах алхмуудыг гүйцэтгэнэ.

1. Class Wizard-г нээ. 2. Member Variables хавтсыг сонго.

3. Хувьсагч хавсаргах контролынхоо ID –г сонго. (IDC_MSG) 4. Add Variable товчийг дар. 5. Дээрх байдлаар хувьсагчаа өгнө.

6. Бусад контролуудад хувьсагч хавсаргахын тулд 3-5 алхмуудыг давтан хийнэ. 4. Бидний программд дараах хувьсагчуудыг хавсаргах шаардлагатай.

Control Variable Name Category Type IDC_MSG m_strMessage Value CString IDC_PROGTORUN m_strProgToRun Value CString

Page 7: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 7 

IDC_CKENBLMSG m_bEnableMsg Value BOOL IDC_CKENBLPGM m_bEnablePgm Value BOOL IDC_CKSHWMSG m_bShowMsg Value BOOL IDC_CKSHWPGM m_bShowPgm Value BOOL

5. Хувьсагчидаа хавсаргаж дууссан бол Class Wizard2-г хаа. 6. Контролуудад хийгдэх үйлдлийг программчилна. Бидний программын хувьд эхлэ

цонх үүсэхэд контролуудыэд

н анхны утгыг хавсаргасан хувьсагчидаар дамжуулан

essage Maps хавтасны member functions хэсгээс OnInitDialog

3. TOD кодыг нэмнэ.

хаар утга олгож байна.

ролууд руу, эсрэг тохиодолд контролуудаас

үүргийг

өмнөх

2. Edit Cod гдсэн функц дээр үйлдэл нэмнэ. id CDay

control notification handler code here

3. Show M аах үйлдлийг нэм. id CDay

тодорхойлно. Үүний тулд 1. Class Wizard-н M

функцыг сонго.

2. Edit Code товчийг дар. O тэмдэглэгээний дараа өөрийн программын TODO: Add extra initialization here //message цонхон дээр олгох анхны текст

re"; m_strMessage = "Place a message heгогдсон бай //бүх checkbox-уудыг сон

m_bShowMsg = TRUE; m_bShowPgm = TRUE; m_bEnableMsg = TRUE; m_bEnablePgm = TRUE; // дээрх утгуудаар контролуудыг идэвхжүүлж байна. UpdateData(FALSE);

4. UpdateData функц нь контрол болон хувьсагчдын хоорондох тулхүүр болдог. Өөрөөр хэлбэл хувьсагчдаас контролууд руу эсвэл контролуудаас хувьсагчуудруу утгыг дамжуулах үүргийг гүйцэтгэдэг. Үүнийг аргументын утгаас хамаарч хийнэ. Худал бол хуьсагчдаас конхувьсагчид руу утгыг дамжуулна.

5. 7. Товчнуудын хийх үйлдлийг хийж өгье. Эхлээд программаас гарах Exit товчны

хийе. Үүний тулд Class Wizard-с IDC_EXIT обьектын BN_CLI1. CKED message дээрлаборатори дээрх шиг функц нэм.

eo товчийг дарж нэмэ

v 2Dlg::OnExit() { // TODO: Add your OnOK();

} eossage товчин дээр дар

v 2Dlg::OnShwmsg() {

Page 8: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 8 

dler code here UpdateData(TRUE);

а хөрвүүлж шалгахад Show Message товчийг дарахад дараах цонх рч ирнэ.

5. Clear M ge товчин дээр дараах кодыг хий.

ation handler code here m_strMessage="";

6. уд дээр үүргийг нь нэмэх шаардлагатай. Дараах

//IDC_CKENBLMSG –д oid CDay

nable Message Action check box тэмдэглэгдсэн байна уу?

tDlgItem(IDC_CLRMSG)->EnableWindow(TRUE); tDlgItem(IDC_STATICMSG)->EnableWindow(TRUE);

tDlgItem(IDC_CLRMSG)->EnableWindow(FALSE); TATICMSG)->EnableWindow(FALSE);

//IDC_CKSHWMSG –д

our control notification handler code here // Get the current values from the screen

tDlgItem(IDC_CLRMSG)->ShowWindow(TRUE); tDlgItem(IDC_STATICMSG)->ShowWindow(TRUE);

// TODO: Add your control notification han MessageBox(m_strMessage); }

4. рограммаПга

essav 2Dlg::OnClrmsg() oid CDay{ // TODO: Add your control notific UpdateData(FALSE); }

Мөн CheckBox контролукодуудыг нэмж өг.

v 2Dlg::OnCkenblmsg() { // TODO: Add your control notification handler code here UpdateData(TRUE); // E if (m_bEnableMsg == TRUE) { // тэмдэглэгдсэн байвал GetDlgItem(IDC_MSG)->EnableWindow(TRUE); GetDlgItem(IDC_SHWMSG)->EnableWindow(TRUE); GetDlgItem(IDC_DFLTMSG)->EnableWindow(TRUE); Ge Ge } else { // тэмдэглэгдээгүй байвал GetDlgItem(IDC_MSG)->EnableWindow(FALSE); GetDlgItem(IDC_SHWMSG)->EnableWindow(FALSE); GetDlgItem(IDC_DFLTMSG)->EnableWindow(FALSE); Ge GetDlgItem(IDC_S } }

v y2Dlg::OnCkshwmsg() oid CDa{ // TODO: Add y UpdateData(TRUE); // Is the Show Message Action check box checked? if (m_bShowMsg == TRUE) { // Yes, so show all controls that have anything // to do with showing the user message GetDlgItem(IDC_MSG)->ShowWindow(TRUE); GetDlgItem(IDC_SHWMSG)->ShowWindow(TRUE); GetDlgItem(IDC_DFLTMSG)->ShowWindow(TRUE); Ge Ge } else { // No, so hide all controls that have anything // to do with showing the user message GetDlgItem(IDC_MSG)->ShowWindow(FALSE); GetDlgItem(IDC_SHWMSG)->ShowWindow(FALSE); GetDlgItem(IDC_DFLTMSG)->ShowWindow(FALSE);

Page 9: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 9 

_CLRMSG)->ShowWindow(FALSE); GetDlgItem(IDC_STATICMSG)->ShowWindow(FALSE);

функц бөгөөд харин GetDlgItem(IDC_DFLTMSG) функц нь ектын эцэг класс болох CWnd классын

лж ажиллагааг нь шалга. Программаас өөр программ ажиллуулах үйлдлийг ComboBox-н сонголтоос хамааруулан Run Program товчинд нэмнэ. (IDC_RUNPG

()

n handler code here

gmName

rPgmNa_SHOW);

rPgmNa WinExec("sol.exe",SW_SHOW);

);

10. Даалгавар:

nter a message here” мөрийг EditBox-д хийх үйлдлийг

2. Program Action-ы үйлдлүүдийг нэм. 3. OnRunpgm функцийг хэрэглэгч өөрөө программ зааж ажиллуулдаг болгон өөрчил.

  

GetDlgItem(IDC } }

8. Өмнө бичсэн программын кодыг тайлбарлавал 1. Контролуудаас хувьсагчид утгыг нь авна. (UpdateData(TRUE);) 2. CheckBox тэмдэглэгдсэн эсэхийг шалгана. 3. Хэрэв утга ҮНЭН бол контролуудыг идэвхжүүлэх эсвэл харагдуулах

(EnableWindow(TRUE), ShowWindow(TRUE);) үйлдлийг хийнэ. 4. Эсрэг тохиолдолд контролуудыг идэвхгүй болгох эсвэл нууцлах

(EnableWindow(FALSE), ShowWindow(FALSE);) үйлдлийг хийнэ. Энэ функц нь CWnd хэмээх классын гишүүнIDC_DFLTMSG идентификатортой обьзаагч утгыг буцаадаг.

9. Программаа хөрвүү

M) void CDay2Dlg::OnRunpgm{ // TODO: Add your control notificatio UpdateData(TRUE); CString strPgmName; strP =m_strProgToRun; strPgmName.MakeUpper(); if (st me=="PAINT") WinExec("pbrush.exe",SW if (st me=="SOLITAIRE") if (strPgmName=="NOTEPAD")

WinExec("NotePad.exe",SW_SHOW }

Программыг хөрвүүлж ажиллагааг шалга.

1. Default Message товчийг дарахад “Eнэм.

                  

Page 10: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 10 

Lecture №5-6

цонхтой программ бичих дадлага эзэмшинэ. Дараах рааллаар хийнэ үү!

cation үүсгэ. 2.

ролууд болон ад хавсаргах хувьсаг чанар

Сэдэв: Программд шинээр диалог нэмэх Өнөөдөр бид хэд хэдэн да 1. My Documents директорт Dialogs нэртэй Dialog Based Appli

Үндсэн цонхны харагдах байдлыг дараах байдлаар өөрчил.

3. Конт контролууд чид. Төрөл Шинж УтгаCommand Button ID IDC_BSHWFONTDLG Caption Show Font DialogCommand Button ID IDC_BSHWPICDLG Caption ShowPicture DialogCommand Button ID IDC_BSHWCSTMDLG Caption Show Custom DialogCommand Button ID IDC_BSHWFOPENDLG Caption pen DialogShow File OCommand Button ID IDC_BEXIT Caption ExitGroup Box ID IDC_GBTOOL Caption Drawing Tool Disabled Checked Group Box ID IDC_GBSHAPE Caption Drawing Shape Disabled Checked Group Box COLOR ID IDC_GB Caption Color Disabled Checked Radio Button N ID IDC_RTPE Caption Pen Group Checked Disabled Checked

Page 11: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 11 

dio Button BRUSH Ra ID IDC_RT Caption Brush Disabled Checked Radio Button TMAP ID IDC_RTBI Caption Bitmap Disabled Checked Radio Button SLINE ID IDC_R Caption Line Group Checked Disabled Checked Radio Button RCLE ID IDC_RSCI Caption Circle Disabled Checked Radio Button UARE ID IDC_RSSQ Caption Square Disabled Checked Radio Button BLACK ID IDC_RC Caption Black Group Checked Disabled Checked Radio Button CBLUE ID IDC_R Caption Blue Disabled Checked Radio Button GREEN ID IDC_RC Caption Green Disabled Checked Radio Button CCYAN ID IDC_R Caption Cyan Disabled Checked Radio Button RCRED ID IDC_ Caption Red Disabled Checked Radio Button ENTA ID IDC_RCMAG Caption Magenta Disabled Checked Radio Button LLOW ID IDC_RCYE Caption Yellow Disabled Checked Radio Button WHITE ID IDC_RC Caption White Disabled Checked Command Button ID IDC_BOPENBMP Caption Choose Bitmap File Disabled Checked Static Text ID IDC_OPTION Caption ng> <Null StriStatic Text ID IDC_TEXT Caption > <Null StringStatic Text ID IDC_STATIC Caption File Name:

Page 12: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 12 

Edit Box ID IDC_EFILEPATH Контролуудад хавсаргасан хувьсагчид.

4. Exit товчийг дарахад цонхыг хаах үйдлийг нэм. 5. Show File Open Dialog товчийг дарахад гүйцэтгэх үйлдэл

void CDialogsDlg::OnBshwfopendlg() { // TODO: Add your control notification handler code here CFileDialog m_ldFile(TRUE); if (m_ldFile.DoModal()==IDOK) { //Хэрэв ямар нэг файл сонгогдсон бол нэрийг нь авах m_strResults=m_ldFile.GetFileName(); UpdateData(FALSE); } }

6. Программаа хөрвүүлээд ажиллагааг нь шалга. 7. Show Custom Dialog товчийг дарахад хийгдэх үйлдлийг нэмнэ. Энэ нь

программистийн нэмсэн цонхыг modal хэлбэрээр харагдуулах ба хэрэглэгчээр нэг сонголт хийлгэх ба мөн текстийг гараас оруулах ба оруулсан текстийг IDC_TEXT контролд, сонголтыг IDC_OPTION контрол текст хэлбэрээр дамжуулах үйлдлүүд байна. Эдгээр үйлдлүүдийг дараах алхмаар хийнэ.

7.1. Шинээр диалог нэмнэ. Resource View->Dialogs(right click)->Insert Dialog.

7.2. Нэмэгдсэн диалогийн ID-г IDD_MSG_DIALOG болгон өөрчил. 7.3. Харагдах байдлыг доорхиор өөрчил.

Page 13: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 13 

7.4. Контролууд Төрөл Шинж чанар УтгаCommand Button ID IDOK Caption OkCommand Button ID IDCANCEL Caption Cancel Group Box ID IDC_STATIC Caption Select an Option Radio Button ID IDC_RADIO1 Caption Option1 Group Checked Radio Button ID IDC_RADIO2 Caption Option2 Radio Button ID IDC_RADIO3 Caption Option3 Radio Button ID IDC_RADIO4 Caption Option4 Static Text ID IDC_STATIC Caption Enter a Message Edit Box ID IDC_EDIT1

7.5. Диалог үүсгээд харагдах байдлыг өөрчлөхөөс гадна программд дамжуулан ашиглах обьектыг үүсгэх хэрэгтэй. Үүний тулд тухайн диалогийн Class Wizard цонхыг нээхэд шинэ класс үүсгэх эсэхийг асууна. Шинэ класс үүсгэх цонхонд нэрийг нь CdlgMsg гэж өгөөд Dialog ID-д үүсгэсэн цонхны ID болох IDD_MSG_DIALOG –г тодорхойлоод Base Class-д CDialog классыг өгөөд Ok товчийг даран үүсгэнэ.

7.6. Контролуудад хавсаргах хувьсагчид IDC_EDIT1 CString m_strText IDC_RADIO1 Int m_iOption

7.7. Цонхыг ачаалахад хувьсагчдын анхны утгыг тодорхойлно. m_iOption=0; m_strText=""; UpdateData(false); Дээрхи мөрүүдийг OnInitDialog функцэд нэм.

8. Show Custom Dialog товчийг дарахад үүсгэсэн цонхоо дуудахын тулд тухайн класс төрлийн хувьсагчийг дуудах цонхны обьект болох CDialogsDlg класст зарлах хэрэгтэй. (Class View->(Right click on CDialogsDlg) Add Member Variable)

Page 14: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 14 

Variable Type: CdlgMsg Variable Name: m_dlgMsg 9. Show Custom Dialog товчийг дарахад хийгдэх үйлдлүүд

void CDialogsDlg::OnBshwcstmdlg() { // TODO: Add your control notification handler code here if (m_dlgMsg.DoModal()==IDOK) { m_strOption="Option"; m_strOption+=" Was Selected."; m_strText=m_dlgMsg.m_strText; UpdateData(false); } else { m_strText="Canceled"; UpdateData(false); } }

10. Show Font Dialog товчийг дарахад хийгдэх үйлдлийг нэм. Энэ товчийг дарахад дараах цонх modal хэлбэрээр харагдах ба Sample Text дотор бичигдсэн текстийг Font Sample хэсэгт Select a Font –с сонгогдсон бичгийн хэлбэрээр харагдуулна. Close товчийг дарахад цонхыг хаана.

11. Дээрх үйлдлийг хийхийн тулд дараах алхмуудыг гүйцэтгэнэ. 11.1. Шинээр IDD_FONT_DIALOG нэртэй диалог нэмнэ. 11.2. Ашиглагдах контролуудыг байрлуулна.

Төрөл Шинж чанар УтгаCommand Button ID IDCLOSE Caption CloseТөрөл Шинж чанар Утга

Page 15: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 15 

atic Text St ID IDC_STATIC Caption Sample Text Static Text ID IDC_STATIC Caption Select a Font Edit Box ID IDC_ESAMPTEXT List Box ID IDC_LFONTS Group Box ID IDC_STATIC Caption Sample Font Static Text ID IDC_DISPLAYTEXT Caption <null string> Maximized in a group box

11.3. Программд ашиглах классыг үүсгэнэ. (CFontDlg) тролуудад хавсаргах хувьсагчид 11.4. Кон

IDC_ESAMPTEXT CString m_strSampText IDC_DISPLAYTEXT CString m_strDisplayTextIDC_DISPLAYTEXT tCStatic m_ctlDisplayTexIDC_LFONTS CString m_strFontName IDC_LFONTS CListBox m_ctlFontList

11.5. Close товчийг дарахад цонхыг хаах үйлдлийн кодыг нэм. 11.6. Цонх үүсэхэд ListBox-д үйлдлийн системд суулгасан бүх бичгийн

шрифтийн авах үйлдлийг хийнэ. Үүнийг тусад нь функц хэлбэрээр

. (Class view->(Right click on CFontDlg)Add

n->FillFontList 11.9. х үйлдэл

List()

рөл

t(); //ListBox-г цэвэрлэж

дэхь фонтуудын

. > 0; iCurCount--)

хийе. 11.7. Шинээр функц нэмье

Member Function)

11.8. Function Type-> void, Function Declaratio

Шинээр нэмэгдсэн функцэд хийгдэvoid CFontDlg::FillFont{ int iCount; int iCurCount; CString strCurFont; CString strPrevFont=""; LOGFONT lf; //Font бүтэц тө lf.lfCharSet = DEFAULT_CHARSET; strcpy(lf.lfFaceName, ""); m_ctlFontList.ResetContenбайна. CClientDC dc (this); ::EnumFontFamiliesEx((HDC) dc, &lf,(FONTENUMPROC) EnumFontFamProc, (LPARAM) this, 0); //системнэ авах функц рийг iCount = m_ctlFontList.GetCount(); // ListBox дахь элементүүдийн сүүлчийнхээс эхнийх хүртэлдавтаад // давхацсан элементүүдийг хайж давхцлыг арилгаж байна for (iCurCount = iCount; iCurCount { // Идэвхтэй фонтын нэрийг авах

Page 16: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 16 

strCurFont); уу?

байна

}

Proc(LPENUMLOGFONT lpelf,

ontList функцийг цонх эхэлж ачаалагдахад дуудах

// Set big icon

дэх текст

will not

()

handler code here

_s SampText;

ox

m_ctlFontList.GetText((iCurCount - 1), // Өмнөхтэйгээ адил нэртэй байна

(strCurFont == strPrevFont) if { // тийм бол устга

m_ctlFontList.DeleteString((iCurCount - 1)); } // өмнөх фонтыг идэвхжүүлж

strPrevFont = strCurFont; }

11.10. Үүнд байгаа EnumFontFamProc нь функцийн нэр бөгөөд EnumFontFamiliesEx функц нь фонтыг олоод дуудах функц юм.Иймээсэнэ функцийг global хэлбэрээр зарлах хэрэгтэй Үүний тулд классы тодорхойлж өгөх шаардлагатай. н header файлд (FontDlg.h)

#endif // _MSC_VER > 1000 int CALLBACK EnumFontFamNEWT TMET p m, LP EX RIC l nt

DWORD nFontType, long lParam); // FontDlg.h : header file

Харин g.cpp) бичиж өгнө. хийгдэх үйлдлийг source файлд (FontDlstatic char THIS_FILE[] = __FILE__; #endif int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,

lParam) LPNEWTEXTMETRIC lpntm, DWORD nFontType, long {

ow // Create a pointer to the dialog wind CFontDlg* pWnd = (CFontDlg*) lParam; // Add the font name to the list box pWnd->m_ctlFont

>elfLoList.AddString(lpelf-

gFont.lfFaceName); 1 to continue font enumeration // Return

return 1; } //////////////// //////////////////////////////////////

/////////

////////////// // CFontDlg dialog

11.11. FillFхэрэгтэй. BOOL CFontDlg::OnInitDialog() {

CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE);

; SetIcon(m_hIcon, FALSE) // TODO: Add extra initialization here FillFontList();

return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }

11.12. Sample Text дэхь текст өөрчлөгдөхөд Font Sample мөн дагаж өөрчлөгдөх естой. id vo CFontDlg::OnChangeEsamptext()

{ // TODO: If this is a RICHEDIT control, the control // send this notification unless you override the CDialog::OnInitDialog()

ion and call CRichEditCtrl().SetEventMask // funct // with the ENM_CHANGE flag ORed into the mask. // TODO: Add your control notification

UpdateData(TRUE); m_strDisplayText = m tr

UpdateData(FALSE); }

11.13. ListBox-с фонтын нэрийг сонгоход өөрөөр хэлбэл ListBдахь сонголт өөрчлөгдөхөд Font Sample дахь текстийн фонт

Page 17: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 17 

йг хийхийн тулд мөн нэмэлт SetMyFont

эгш өнцгийн хэмжээг авах

ах хувьсагч

?

);

bottom; sitive

CHARACTER_PRECIS, , DEFAULT_PITCH |

// Set the font for the sample display area

11.14. сонголт өөрчлөгдөхөд даж

ol notification handler code here (TRUE);

w Font Dialog товчийг дарахад гарч ирэх цонхны хувьсагчийг , товчийг дарахад хийгдэх үйлдлийг

нэм

r code here

, сонголтууд илтгэх

ийн хувьсагч нэмнэ. уудыг CPaintDlg обьектын кон .

)

lg) nitialization

ck

өөрчлөгдөх ёстой. Үүнифункцийг CfontDlg класст нэмнэ. void CFontDlg::SetMyFont() {

CRect rRect; // Font Sample –н т хувьсагч

йг ав int iHeight; // өндөри // Фонт сонгогдсон байна уу if (m_strFontName != "") { // Font Sample гарах m_ctlDisplayText.GetWindowRect(&rRect

area height // Calculate the iHeight = rRect.top - rRect. // Make sure the height is po if (iHeight < 0) iHeight = 0 - iHeight; // Release the current font m_fSampFont.Detach(); // Create the font to be used

, 0, 0, 0, FW_NORMAL, m_fSampFont.CreateFont((iHeight - 5) 0, 0, 0, DEFAULT_CHARSET, OUT_

CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY FF_DONTCARE, m_strFontName);

m_ctlDisplayText.SetFont(&m_fSampFont);

} } Нэмсэн дээрх функцээ ListBox-д дуу ажиллуулах хэрэгтэй. void CFontDlg::OnSelchangeLfonts() { // TODO:

UpdateData Add your contr

// Set the font for the sample SetMyFont(); }

12. Sho(m_FontDlg) CdialogsDlg класст зарлан

. void CDialogsDlg::OnBshwfontdlg() { // TODO: Add your control notification handle m_FontDlg.DoModal(); }

13. Программаа хөрвүүлж ажиллагааг нь шалга. 14. Show Picture Dialog товчийг дарахад цонхон дээр зураг зурах, зургийн

файл дуудаж үзүүлэх зэрэг үйлдэл хийх бөгөөд цонх нь ердийн хэлбэрээр гарч ирнэ. Мөн цонхон дээрх зургийн шинж чанарыг тодорхойлох сонголтууд идэвхтэй болно. Товчийг дахин дарахад дээрхи цонх хаагданаидэвхгүй болно. Үүний тулд зургийн цонх харагдаж байгаа эсэхийгбулийн төрлийн хувьсагч авч ашиглая. (BOOL m_bPaintVis;)

Зураг зурах цонх шинээр нэм (IDD_PAINT_DIALOG) 14.1.14.2. Бүх контролуудыг нь устгаад, Maximize, Minimize товчнуудыг

идэвхжүүл, хэмжээг нь өөрчлөх боломжтой болго. 14.3. Тухайн цонхны классыг шинээр үүсгэ. (CPaintDlg) 14.4. Зурагдах өнгийг зохицуулахын тулд COLORREF төрл

(COLORREF mr_Colors[8]). Өнгөний утгструктор функцэд тодорхойлж өгнө

CPaintDlg::CPaintDlg(CWnd* pParent /*=NULL*/ : CDialog(CPaintDlg::IDD, pParent) { //{{AFX_DATA_INIT(CPaintD // NOTE: the ClassWizard will add member ihere //}}AFX_DATA_INIT

a m_crColors[0] = RGB( 0, 0, 0); // Bl m_crColors[1] = RGB( 0, 0, 255); // Blue

m_crColors[2] = RGB( 0, 255, 0); // Green m_crColors[3] = RGB( 0, 255, 255); // Cyan m_crColors[4] = RGB( 255, 0, 0); // Red m_crColors[5] = RGB( 255, 0, 255); // Magenta

Page 18: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 18 

х

void DrawLine(CPaintDC *pDg, int iColor); // зурах функц id CP int iColor)

;

EFRAME, 1, m_crColors[iColor]); a

een each of the lines

points

t pens

on?

SelectObject(&lSolidPen);

Pen);

&lNullPen);

lectObject(&lInsidePen);

next position liDist;

iShapeint iTool, int

m_crColors[6] = RGB( 255, 255, 0); // Yellow m_crColors[7] = RGB( 255, 255, 255); // White }

14.5. Энэ цонхон дээр туршилтын хэлбэрээр зураг зурах бөгөөд зурагдатөрлийг үндсэн цонхноос удирдана. Зурагдах хэлбэр нь Drawing Tool –д заагдсан байгаа. Үүнд 3 төрлийн хэлбэр байгаа бөгөөд эдгээр класст нэмнэ. ийг тус бүрд нь зурах 3 функцыг CPaintDlg

шулуунvo aintDlg::DrawLine(CPaintDC *pdc,{ // Declare and create the pens CPen lSolidPen (PS_SOLID, 1, m_crColors[iColor]); CPen lDotPen (PS_DOT, 1, m_crColors[iColor]); CPen lDashPen (PS_DASH, 1, m_crColors[iColor]); CPen lDashDotPen (PS_DASHDOT, 1, m_crColors[iColor]); CPen lDashDotDotPen (PS_DASHDOTDOT, 1, m_crColors[iColor])

m_crColors[iColor]); CPen lNullPen (PS_NULL, 1,SID CPen lInsidePen (PS_IN

// Get the drawing are CRect lRect; GetClientRect(lRect);

ect(); lRect.NormalizeR // Calculate the distance betw CPoint pStart; CPoint pEnd; int liDist = lRect.Height() / 8; CPen *lOldPen; // Specify the starting pStart.y = lRect.top; pStart.x = lRect.left; pEnd.y = pStart.y; pEnd.x = lRect.right; int i; // Loop through the differen for (i = 0; i < 7; i++) { // Which pen are we switch (i) {

/ Solid case 0: / lOldPen = pdc-> break;

/ Dot case 1: / pdc->SelectObject(&lDotPen); break; case 2: // Dash pdc->SelectObject(&lDashPen); break; case 3: // Dash Dot pdc->SelectObject(&lDashDotPen); break;

Dot Dot case 4: // Dash pdc->SelectObject(&lDashDotDot break; case 5: // Null pdc->SelectObject( break;

/ Inside case 6: / pdc->Se

break; } // Move down to the pStart.y = pStart.y + pEnd.y = pStart.y; // Draw the line pdc->MoveTo(pStart); pdc->LineTo(pEnd); } // Select the original pen pdc->SelectObject(lOldPen); }

void DrawRegion(CPaintDC *pDC, int iColor, int iTool, int ); //дүрс зурах void CPaintDlg::DrawRegion(CPaintDC *pdc, int iColor, iShape) { CPen lSolidPen (PS_SOLID, 1, m_crColors[iColor]); CPen lDotPen (PS_DOT, 1, m_crColors[iColor]);

Page 19: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 19 

; olor]);

);

;

); or]);

f the drawing regions

.Width() / 4; z - 10;

he brushes and pens ; i++)

is figure.

ht;

;

th; brush

);

th;

brush

th; h

l .

th;

ush );

CPen lDashPen (PS_DASH, 1, m_crColors[iColor]); CPen lDashDotPen (PS_DASHDOT, 1, m_crColors[iColor]); CPen lDashDotDotPen (PS_DASHDOTDOT, 1, m_crColors[iColor]) CPen lNullPen (PS_NULL, 1, m_crColors[iC CPen lInsidePen (PS_INSIDEFRAME, 1, m_crColors[iColor] // Declare and create the brushes CBrush lSolidBrush(m_crColors[iColor]); CBrush lBDiagBrush(HS_BDIAGONAL, m_crColors[iColor]); CBrush lCrossBrush(HS_CROSS, m_crColors[iColor]); CBrush lDiagCrossBrush(HS_DIAGCROSS, m_crColors[iColor])

CBrush lFDiagBrush(HS_FDIAGONAL, m_crColors[iColor]);iColor] CBrush lHorizBrush(HS_HORIZONTAL, m_crColors[

CBrush lVertBrush(HS_VERTICAL, m_crColors[iColsh(RGB(192, 192, 192)); CBrush lNullBru

// Calculate the size o CRect lRect; GetClientRect(lRect); lRect.NormalizeRect(); int liVert = lRect.Height() / 2; int liHeight = liVert - 10; int liHorz = lRect int liWidth = liHor CRect lDrawRect; CPen *lOldPen; CBrush *lOldBrush; int i;

all of t // Loop through for (i = 0; i < 7 { switch (i) { case 0: // Solid // Determine the location for th // Start the first row lDrawRect.top = lRect.top + 5; lDrawRect.left = lRect.left + 5; lDrawRect.bottom = lDrawRect.top + liHeig lDrawRect.right = lDrawRect.left + liWidth; // Select the appropriate pen and brush

SolidPen); lOldPen = pdc->SelectObject(&l lOldBrush = pdc->SelectObject(&lSolidBrush) break; case 1: // Dot - Back Diagonal // Determine the location for this figure.

lDrawRect.left = lDrawRect.left + liHorz;ft + liWid lDrawRect.right = lDrawRect.le

// Select the appropriate pen and ctObject(&lDotPen); pdc->Sele

pdc->SelectObject(&lBDiagBrush break; case 2: // Dash - Cross Brush // Determine the location for this figure. lDrawRect.left = lDrawRect.left + liHorz;

+ liWid lDrawRect.right = lDrawRect.left // Select the appropriate pen and pdc->SelectObject(&lDashPen); pdc->SelectObject(&lCrossBrush); break; case 3: // Dash Dot - Diagonal Cross // Determine the location for this figure.

lDrawRect.left = lDrawRect.left + liHorz; liWid lDrawRect.right = lDrawRect.left +

// Select the appropriate pen and brusectObject(&lDashDotPen); pdc->Sel

pdc->SelectObject(&lDiagCrossBrush); break; case 4: // Dash Dot Dot - Forward Diagona // Determine the location for this figure // Start the second row lDrawRect.top = lDrawRect.top + liVert; lDrawRect.left = lRect.left + 5;

ht; lDrawRect.bottom = lDrawRect.top + liHeigWid lDrawRect.right = lDrawRect.left + li

br // Select the appropriate pen and otPen pdc->SelectObject(&lDashDotD

pdc->SelectObject(&lFDiagBrush); break; case 5: // Null - Horizontal // Determine the location for this figure.

lDrawRect.left = lDrawRect.left + liHorz;

Page 20: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 20 

t + liWidth; brush

;

th; brush

Brush);

n);

d pen

void ShowBitmap(CPaintDC *pDC, CWnd *pWnd); // гаргах Wnd)

g*)pWnd;

itmap = (CBitmap*)dcMem.SelectObject(lpWnd-

available

ndow ,

14.6. функцэд дараах үйдлийг нэмнэ.

ting

ndler code here sDlg *pWnd = (CDialogsDlg*)GetParent();

?

shape

drawing a ellipse or rectangle DrawRegion(&dc, pWnd->m_iColor, pWnd->m_iTool,

lDrawRect.right = lDrawRect.lef // Select the appropriate pen and pdc->SelectObject(&lNullPen) pdc->SelectObject(&lHorizBrush); break; case 6: // Inside - Vertical // Determine the location for this figure.

lDrawRect.left = lDrawRect.left + liHorz;+ liWid lDrawRect.right = lDrawRect.left

// Select the appropriate pen andectObject(&lInsidePen); pdc->Sel

pdc->SelectObject(&lVert break; } // Which tool are we using?

ool == 0) if (iT pdc->SelectObject(lNullBrush); else pdc->SelectObject(lNullPe // Which shape are we drawing? if (iShape == 1) pdc->Ellipse(lDrawRect); else pdc->Rectangle(lDrawRect); }

n // Reset the original brush a pdc->SelectObject(lOldBrush); pdc->SelectObject(lOldPen); }

зурагvo aintDlg::ShowBitmap(CPaintDC *pdc, CWnd *pid CP{ CDialogsDlg *lpWnd = (CDialogsDl BITMAP bm; // Get the loaded bitmap lpWnd->m_bmpBitmap.GetBitmap(&bm); CDC dcMem; // Create a device context to load the bitmap into dcMem.CreateCompatibleDC(pdc); // Select th bitmap into the compatible device context e CBitmap* pOldB>m_bmpBitmap); CRect lRect; // Get the display area GetClientRect(lRect); lRect.NormalizeRect(); // Copy and resize the bitmap to the dialog wi pdc->StretchBlt(10, 10, (lRect.Width() - 20) (lRect.Height() - 20), &dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); }

int Dialog-н OnPaint Pavoid CPaintDlg::OnPaint() { CPaintDC dc(this); // device context for pain // TODO: Add your message ha CDialog // Do we have a valid pointer if (pWnd) { // Is the tool a bitmap? if (pWnd->m_iTool == 2) { if (pWnd->m_sBitmap!="") ShowBitmap(&dc,pWnd); } else // No, we're drawing a { // Are we drawing a line? if (pWnd->m_iShape == 0) DrawLine(&dc, pWnd->m_iColor); else // We're pWnd->m_iShape); } } // Do not call CDialog::OnPaint() for painting messages }

Page 21: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 21 

нь . Өөрөөр

д хэсэг нь ил гарч ирсэн зэрэг тохиолдолд

ialog цонхыг үндсэн цонхноос дуудахын тулд logsDlg

14.9. Show P tureid CD

нээр

цонхоо

on нь

дээр OnRtpen функцийн нэрийг OnRSelection болгон солино.

Ингэж йг хийж функцийг тодорхойлж өгнө

cation handler code here

p төрлий агчийг нэм.

14.13.

tification handler code here Files

14.7. Дээрх ОnPaint функц нь WM_PAINT message-н функц бөгөөд энэтухайн цонх дахин зурагдах шаардлагатай үед дуудагддагхэлбэл тухайн цонхны хэмжээг өөрчилсөн, идэвхтэй болсон, зөөсөн, далдуудагдана. Программын аргаар дуудахдаа Invalidate() функцийг ашиглана.

14.8. Шинээр үүссэн Paint DCPaintDlg төрлийн m_dlgPaint нэртэй хувьсагчийг CDiaкласст тодорхойлно.

i Dialog товчийг дарахад хийгдэх үйлдэл lg()

cvo ialogsDlg::OnBshwpicd{ // TODO: Add your control notification handler code here if (!m_bPaintVis) { m_dlgPaint.Create(IDD_PAINT_DIALOG, this);//цонх шиүүсгэх m_dlgPaint.ShowWindow(SW_SHOW);// үүсгэсэндэлгэцэнд харуулах

bPaintVis=true; m_ m_strShowPic="Hide Picture Dialog" UpdateData(false); } else {

; m_dlgPaint.DestroyWindow()_bPaintVis=false; m

m_strShowPic="Show Picture Dialog" UpdateData(false); } GetDlgItem(IDC_GBTOOL)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_GBSHAPE)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_GBCOLOR)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RTPEN)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RTBRUSH)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RTBITMAP)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RSCIRCLE)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RSSQUARE)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RSLINE)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCBLACK)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCBLUE)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCRED)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCGREEN)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCCYAN)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCYELLOW)->EnableWindow(m_bPaintVis);

GetDlgItem(IDC_RCWHITE)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_RCMAGENTA)->EnableWindow(m_bPaintVis); GetDlgItem(IDC_BOPENBMP)->EnableWindow(m_bPaintVis); }

14.10. Drawing Tool, Drawing Shape, Color дэхь сонголтууд өөрчлөгдөхөд Paint цонхон дахь зураг өөрчлөгдөх өөрөөр хэлбэл Paint цонхыг дахин сэргээх шаардлагатай. Бүх Radio Buttадил үйлдэл хийх учир нэг функцийг зааж өгнө. Үүний тулд шинээр функц нэмье. (CDialogsDlg класст (void OnRSelection))

14.11. Харин Radio Button-доо энэ функцийг хэрхэн зааж өгөх вэ? Үүний тулд жишээ нь: Pen Radio Button дээр 2 товшиход гарч ирэхцонхон

бүх Radio Button дээр үйлдли

void CDialogsDlg::OnRSelection() {

// TODO: Add your control notifi UpdateData(TRUE); m_dlgPaint.Invalidate(); }.

14.12. Choose Bitmap File товчийг дарахад зургын файлыг олж, зургыг нь хувьсагчид авч Paint цонхонд дамжуулах үйлдэл хийгдэнэ. Иймээс CDialogsDlg класст зураг дамжуулах CBitma

н m_bmpBitmap нэртэй хувьсChoose Bitmap File товчийг дарахад хийгдэх үйлдэл. void CDialogsDlg::OnBopenbmp() { // TODO: Add your control no static char BASED_CODE szFilter[] = "Bitmap(*.bmp)|*.bmp||"; // Create the File Open dialog

Page 22: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 22 

, m_sBitmap, ITEPROMPT, szFilter);

the result

ceHandle(),

BSECTION); loaded image?

detach it

p to the bitmap object tmap);

хын тулд PaintDlg.cpp logsDlg.h файлын

Paint цонхыг Close товчоор нь хаахад үндсэн цонхонд Hide Paint Dialog овчийг дарсантай адил үйлдлийг хийх функцийг нэм.

 

CFileDialog m_ldFile(TRUE, ".bmp" OFN_HIDEREADONLY | OFN_OVERWR // Show the File Open dialog and capture if (m_ldFile.DoModal() == IDOK) { // Get the filename selected m_sBitmap = m_ldFile.GetPathName(); // Load the selected bitmap file HBITMAP hBitmap = (HBITMAP) ::LoadImage(AfxGetInstan

IMAGE_BITMAP, 0, 0, m_sBitmap, LR_LOADFROMFILE | LR_CREATEDI // Do we have a valid handle for the if (hBitmap) {

p // Delete the current bitma if (m_bmpBitmap.DeleteObject()) // If there was a bitmap, m_bmpBitmap.Detach(); // Attach the currently loaded bitma m_bmpBitmap.Attach(hBi } // Invalidate the second dialog window m_dlgPaint.Invalidate(); } }

14.14. Ингэж Paint цонхонд утга дамжуулафайлын header файл зарлалтын хэсэгт Diaзарлалтыг нэмэх хэрэгтэй.

15. Программаа хөрвүүлж ажиллуулан үр дүнг шалга. Даалгавар: т                           

Page 23: Vizual programchilal cu lekts

Визу

Боло

 

зөвхө

үүсд

КласCEdi CFor

CHtm

CLisCRic

CScrCTre

ӨнөөSDI

уал програ

овсруулсан

SDI прогөн нэг барим

SDI продэг. About

1. CWinхэрэCVie

2. CFraэнэ зохи

3. CDocбариболоба ү

4. CVieобьеклас

сс itView

rmView.

mlView

stView chEditView

rollView eeView

өдрийн лабпрограмм 1. Шинэ2. AppW

тодо3. 3 да

гэсэ4. 4 да5. Гарч

өргө6. Next

амчлал СИ

н багш: Т.

Сэдэврамм гэдэг мт боловсру

ограмм үүсt цонхны кnApp –с удэглэгдэх бew обьектуameView -снь тухайнион байгууcument –с имтын обьеовсруулах үүнээс дэлew–с удамшект. Энэ кссаас удам

ТайлбарEditBoxболовсрХарагдахэлбэриWeb broмэдээлэList ко

w ТэмдэгтболовсрCView кМод хэл

бораториорүүсгэх: ээр Lab4 нWizard эхнорхойл. ахь алхамыэн тэмдэглахь алхмыгч ирэх цонөтгөлийг зt товчийг

И++ хичээл

.Уламбаяр

в: Singleнь баримт буулдаг. Жиш

сгэхэд диаклассыг эсдамшсан клбусад обьеуудын messс удамшсанн цонхон дулах үүрэгудамшсан ект. Үүнд ба энэ кллгэцэнд гашсан класскласс нь дмшиж болнор x контрол руулахад аах байдлынийн мэдээлowser –н үэл боловсронтрол дахт болон хэруулахад хкласст scrлбэрийн мэ

р бид SDI

нэртэй проний алхамд

ыг байгааглэгээг ариг хэвээр ннхон дээрэзааж өгнө.даран дар

лийн лекц

р

Lecture e Documentболовсруулашээ нь Notep

алог прогрс тооцвол ласс. Энэ ектыг тодоsage-уудыгн класс ньдахь обьекгтэй. класс нь баримтандласст бариаргах мэдэс нь баримдэлгэцэнд о. Жнь:

дахь үйлдашиглагддан обьект нлэл боловсүйлдлүүдийруулахад ххь үйдлийгэлбэржүүлсхэрэглэгдэroll хийх эдээлэл бо

хэлбэрийн

ожект үүсгд программ

гаар нь өнилга нь үлдээгэээс програ.(lb4) Cloраагийн ал

ийн хураа

№7-8 t Applicatах программpad, Paint, So

рамм үүсгэдараах клкласс нь орхойлж өгг илгээх дь программктуудыг (t

тухайн прд шаардлагимтад орууээллийг CVмтын дэлгэхарагдах

длийг хийдаг. нь контролсруулахад йг хийдэг.хэрэглэдэгг хийдэг. сэн текст энэ. шинж чанаоловсруула

н, зураг з

гэ. мын төрлий

нгөрөөгөөд

ээд Advancаммын болоose товчийлхамд шилж

ангуй

tion үүсгэмын ерэнхийolitaire гэх м

эснээс хамлассууд үүтухайн пргөх үүрэгтдамжуулах мын цонхныtoolbar, s

рограммын гатай өгөгулах мэдээView руу иэцэнд харабайдлын х

дэг. Ердий

луудыг агухэрэглэгд.Үүнийг URг.

хэлбэрийн

арыг нэмж ахад ашигл

зурдаг про

йн Single

д 4 дэхь а

ced товчийовсруулах йг даран цж.

эх й хэлбэр бөгмэт.

маагүй олоүснэ. рограммд тэй ба CFrүүрэгтэй.ы обьект бscrollbar,

боловсруугдлийн төрэлэл CViewилгээгддэгагдах байдхэд хэдэн

йн текст м

уулж болнодэнэ. RL, Html х

н мэдээлэл

өгнө. лагдана.

ограммыг б

Document

алхмын Act

йг бадар римтын

цонхоо хаа

Page 23

өөд тухайн

он класс

rameView, . бөгөөд ,menu,…)

улах рлийг w-с ирэх г. длын төрлийн

мэдээлэл

о. Form

хэлбэрийн

л

бичнэ.

гэж

tiveX

а.

Page 24: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 24 

ыг

. 1.

Үүнийг

->m_ptFrom гэж өгөөд Ok

CLine)-

бичээд Ok товчийг дар. 7. Нэм

n om, CPoint ptTo) {

;

. Үүний тулд

кц нэм. 2. Нэм длийг нэм.

d CL C) {

г

7. 5 дахь алхам дахь утгуудыг хэвээр үлдээ. 8. 6 дахь алхамд баримтын харагдах байдлын обьекитын удамших класс

CView гэж хэвээр нь үлдээгээд Finish товчийг дарвал AppWizard программыг үүсгэнэ.

Line класс үүсгэх. Энэ программд зураг зурах үйлдэл хийх учир зурагдах дүрс болгонд обьектыг үүсгэх хэрэгтэй. Жишээ нь шулуун зурах класс үүсгэе. Ингэж класс үүсгэснээр шулууны шинж чанаруудыг тодорхойлох боломжтой болно

Class View-> (right click on Lab4 Classes)->New Class

2. Дээрхи байдлаар утгуудыг тодорхойл. 3. OK товчийг дарахад CLine класс шинээр үүснэ.

CLine классын гишүүн өгөгдөл, гишүүн функц, байгуулагч болон устгагч функцүүдийг тодорхойлох.

CLine кл1. асс 2 гишүүн өгөгдөлтэй. (эхлэх цэг, төгсөх цэг) нэмнэ.

2. Class View->(right click on CLine)->Add Member Variable Variable type-3. > CPoint, variable nameтовчийг дар.

4. Дээрх байдлаар m_ptTo өгөгдлийг нэм. Байгуулагч функц нэмэхийн тулд Class 5. View->(right click on>Add Member Function командыг сонго

Function type –г хоосон үлдээгээд function declaration –д 6.CLine(CPoint ptFrom, CPoint ptTo) гэж

сэCLiн функцдээ дараах үйлдлийг хий.e::CLine(CPoint ptFr

m_ptFrom = ptFromm_ptTo = ptTo;

} Зөв обьект хандалтат программд обьект нь өөрөө үйлдлээ хийдэг байх хэрэгтэй. Иймээс CLine класс нь шулуунаа зурдаг байх хэрэгтэйшулуун зурдаг функцыг нэмж өгнө.

1. void төрлийн Draw(CDC *pDc) нэртэй фун сэ

voiн функцдээ дараах үйл

ine::Draw(CDC * pD

// Draw the line pDC->MoveTo(m_ptFrom);pDC->LineTo(m_ptTo);

} Дээрхи нэмсэн классаа баримт боловсруулах CDocument класстайгаа холбож өгөх хэрэгтэй. Өөрөөр хэлбэл шинээр зурагдсан шулууныг баримтад хадгалах хэрэгтэй. Үүний тулд хадгалах динамик массивыг тодорхойлох шаардлагатай. Массив нь CobArray төрлийн хувьсагч байх шаардлагатай. MFC-д CStringArray, CByteArray, CWordArray, CDWordArray,CPtrArray гэсэн массив төрлүүд байда

Page 25: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 25 

атай үйлдэл бол шулуун нэмэх үйлдэл юм. Доорхий функцыг CL

CLine * CLab4Doc::AddLine(CPoint ptFrom, CPoint ptTo) {

eate a new CLine object ne *

try {

ct array ;

he

x("Out of memory", MB_ICONSTOP | MB_OK); Did ne object?

if (pLi{

e exception object ();

Дараагийн зайлшгүй йт хэдэн шулуун зурагдсаныг тоолох. int CLa

эцэст нь зай өн дугаарын шулууны обьектыг тодорхойлох.

CLine *{

ct

жтайгаар гүйцэтгэнэ. Үүний тулд хулганы товч дарагдахад UTTONDOWN, WM_LBUTTONUP, ба WM_MOUSEMOVE

3. Дээ4. Нэмэгдсэн

message handler code here and/or call default

id CL

or call default

s) can

ReleaseCapture();

бөгөөд тус бүр өөр өөрийн тодорхой төрлүүдийн хадгалдаг. Харин CobArray төрөл нь ямарч төрлийн хувьсагчдыг хадгалах чадвартай байдаг. CLab4Doc клөасст CobArray төрлийн m_oaLines нэртэй хувьсагч нэм. Документ класст хийгдэх анхны шаардлаг

ab4Doc класст нэм.

//CLi

CrpLine = new CLine(ptFrom, ptTo);

// Add the new linem_oaLines.Add(pLine)

to the obje

// Mark the document as dirty SetModifiedFlag();

} // Did we run into a memory exception?

ryException* perr) catch (CMemo{

, giving him or her t// Display a message for the user // bad news

xMessageBoAf// we create a li

ne)

// Delete it delete pLine;

LL; pLine = NU} // Delete thperr->Delete

} return pLine; }

хийгдэх үйлдэл бол ниb4Doc::GetLineCount()

{ // Return the array count return m_oaLines.GetSize();

} лшгүй хийгдэх үйлдэл бол өгөгдс

CLab4Doc::GetLine(int nIndex)

// Return a pointer to the line obje// at the specified point in the object array return (CLine*)m_oaLines[nIndex];

} Дараагийн шаардлага бол хэрэглэгч хулганы заагчийн тусламжтайгаар шулуун зурдаг байх. Өөрөөр хэлбэл хулганы зүүн товчийг дараад хулганы заагчийг гүйлгэхэд заагчийн гйүсний дагуу шулуун зурагддаг байх явдал юм. Үүнийг CView классын тусламилгээгддэг message-үүд болох WM_LB–үүдийг ашиглана.

1. Class Wizard цонхыг нээ 2. CLab4View классыг сонго

рхи 3 message тус бүрд функц нэм. функцүүдэд дараах үйлдлийг хий.

n(UINT nFlags, CPoint point) void CLab4View::OnLButtonDow{ // TODO: Add your SetCapture();

// Save the point m_ptPrevPos = point;

CView::OnLButtonDown(nFlags, point); }

, CPoint point) vo ab4View::OnLButtonUp(UINT nFlags{ // TODO: Add your message handler code here and/

aptured the mouse? // Have we c if (GetCapture() == thi // If so, release it so other applications

// have it

Page 26: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 26 

tton is down TTON)

ocument()->AddLine(m_ptPrevPos, point);

ious point

ж

ин зурах шаардл ардлагатай гэсэн утга WM_PAINT message-р ирснээр ункцийг нэмж өгөх хэрэгтэй.

ument

lines in the document?

s++)

o point for each line ine(liPos);

// Draw the line

рлах шаардлагатай. ab4View.cpp файлуудад Line.h файлыг зарлах хэрэгтэй.

удын Харин DeleteContents

функцэд цэвэ . Ийм функц байхгүй байвал ClassWizard- нэмэ

CView::OnLButtonUp(nFlags, point); } void CLab4View::OnMouseMove(UINT nFlags, CPoint point){ // TODO: Add your message handler code here and/or call default // Check to see if the left mouse bu

_LBU if ((nFlags & MK_LBUTTON) == MK { // Have we captured the mouse?

if (GetCapture() == this) { // Get the Device Context CClientDC dc(this); // Add the line to the document CLine *pLine = GetD // Draw the current stretch of line pLine->Draw(&dc); // Save the current point as the prev m_ptPrevPos = point; } } CView::OnMouseMove(nFlags, point); }

Дээр дуудагдсан SetCapture функц нь хулганы товч дарагдахад хийгдэх ба энэ нь хулганы заагчийг зөвхөн өөрийн программд ажиллах боломжтой болгодог. Шалтгаан нь жишээ нь хулганы заагчийг чирж байгаад зураг зурах цонхноос хэтрээд гарч яваад буцаж орж ирэх тохиолдолд шулуун зурсан хэвээр байна гэзааж өгч байна. Өөрөөр хэлбэл бусад программд хулганы талаархи message-үүдийг илгээхгүй болгож байна. Харин ReleaseCapture функц нь үүний эсрэг юм. Хулганыг зөөж байх агшинд баримтад шулуун нэмж байна. View класс дахь шаардлагатай үйлдэл бол CView обьект дахин сэргээгдэх (зурагдах) ш лд баримт дахь шулуун болгоныг дахаардлагатай болсон тохиолдо

атай. Дахин сэргээгдэх шаагмэдэгддэг. Иймээс доорхи ф

void CLab4View::OnDraw(CDC* pDC) { CLab4Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here // Get the number of lines in the doc

pDoc->GetLineCount(); int liCount = // Are there any if (liCount)

{ int liPos; CLine *lptLine; // Loop through the lines in the document for (liPos = 0; liPos < liCount; liPo { // Get the from and t

lptLine = pDoc->GetL

lptLine->Draw(pDC); } } }

аас өмнө CLine классын Программаа хөрвүүлж ажиллагааг нь шалгаходорхойлолтыг шаардлагатай обьектуудад зат

Lab4Doc.cpp ба LПрограммаа хөрвүүлж ажиллагааг нь шалга. Шинээр баримт үүсгэх. Программын документ класст байгаа OnNewDocument функц нь дэлгэцэнд байгаа зургийг устгахгүй харин New командыг (цэсний) сонгоход бусад классуэхний утгууд үдийг хийдэг. ыг тодорхойлох зэрэг үйлдлү

эх үйлдлийг хийх хэрэгтэйрл р х боломжтой. Дараах үйлдлийг хий.

void CLab4Doc::DeleteContents()

Page 27: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 27 

Add your specialized code here and/or call the base class

leting each object liCount; liPos++)

х элемент (шул чид хадгалж байгаа учир зөвхөн энэ хувьсагч цийг дуудахад хангалттай.

ж байгаа рөөр хэлбэл CLine классын

Serialize фу e класст дээрх функцийг тодорхойлох

rchive &ar)

} Программаа хөрвүүлж ажиллагааг гарна.

дарт функц бөгөөд энэ нь DECLARE_SERIAL, IMPLEM дорхойлолтуудыг зарласнаар алдаагүй ажиллана

AL (CLine)

Харин Line.cntation of the CLine class.

///////////////////////////////////////////////////

fx.h"

{ // TODO: // Get the number of lines in the object array int liCount = m_oaLines.GetSize(); int liPos; // Are there any objects in the array? if (liCount) {

ay, de // Loop through the arr for (liPos = 0; liPos < delete m_oaLines[liPos]; // Reset the array m_oaLines.RemoveAll(); }

eleteContents(); CDocument::D}

Дээрх функц нь шинээр баримт нээхэд гарч болох алдаануудыг багасгана. Баримтаа хадгалах ба нээх. AppWizard нь хэдийгээр Save, Open, Save as цэснүүдийгүүсгэдэг боловч хийгдэх үйлдлийг нь өөрсдөө хийх шаардлагатай. Эдгээр үйлдлүүдийг Serialize гэж нэрлэдэг бөгөөд файлд хадгалах, файлаас унших үйлдлийг CLab4Doc классын Serialize хэ хувьд баримтын бүмээх функцэд хийж өгнө. Бидний программын

н) нь m_aoLines хэмээх хувьсагууийн файлд хадгалах стандарт функvoid CLab4Doc::Serialize(CArchive& ar) { m_oaLines.Serialize(ar); }

Харин m_aoLines хувьсагчийн Serialize функц нь дотор нь хадгалагдахувьсагчдын Serialize функцыг дууддаг. Өө

цыг дуудна. Иймээс бид CLinнкшаардлагатай. void CLine::Serialize(CA{ CObject::Serialize(ar); if (ar.IsStoring()) ar << m_ptFrom << m_ptTo; else ar >> m_ptFrom >> m_ptTo;

шалгахад дараах алдаа

Учир нь Serialize гэдэг нь стан_SERIAL гэсэн макро тоENT. Ий

class CLinмээс Line.h файлд

e : public CObject {

DECLARE_SERIpublic:

e(CPoint ptFrom, CPoint ptTo); CLinpp файлд // Line.cpp: impleme// /////////////////// #include "stda#include "Lab4.h"#include "Line.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif

Page 28: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 28 

/////////////////////////////////////////////////////// Destruction

///////////////////////////////////////////////////////////////////

лагатай. Одоо программаа хөрвүүлж ажиллагааг

ber Varialble тодорхойлон

Ok 3. CLi кцийг өөрчил.

int ptTo, COLORREF crColor)

4. Мөн функцүүд өөрчлөгдөнө.

e drawing object >SelectObject(&lpen);

pDC->LineTo(m_ptTo);

л

UINT m_nColor, static const COLORREF m_crColors[8] 2. M_crColor файлд тодорхойл.

= {

ta

///////////////////////////////////////////

3. Мөн доошл функцүүдэд өөрчлөлт хийгдээд

IMPLEMENT_SERIAL (CLine, CObject, 1) ///////////////// Construction//// CLine::CLine() { }

гэж тус тус өөрчлөлт хийх шаарднь шалгахад алдаа гарахгүй ба зурсан зургаа хадгалдаг, хадгалсан зургаа нээдэг болсон байна. Цэстэй ажиллах, өнгө оруулах. Одоо программаа хэрэглэгчийн сонгосон өнгөөр зурдаг болгон үйлдэл нэмье. Үүний тулд CLine класстаа шинээр өнгө тодорхойлсон хувьсагч нэмнэ.

1. Class View->(right click on Cline)->Add Mem2. Variable type->COLORREF, Variable name->m_crColor гэж

вчийг дар. тоne классын байгуулагч фун

CPoCLine::CLine(CPoint ptFrom, { m_ptFrom=ptFrom; m_ptTo=ptTo; m_crColor=crColor; } Draw, Serialize void CLine::Draw(CDC *pDC) { // Create a pen

D, 1, m_crColor); CPen lpen (PS_SOLI // Set the new pen as th

C- CPen* pOldPen = pD // Draw the line pDC->MoveTo(m_ptFrom); // Reset the previous pen pDC->SelectObject(pOldPen); }

rchive &ar) void CLine::Serialize(CA{ CObject::Serialize(ar); if (ar.IsStoring()) ar << m_ptFrom << m_ptTo<<(DWORD) m_crColor; else ar >> m_ptFrom >> m_ptTo>> (DWORD) m_crColor; }

Ингэж CLine класст үйлдэл нэмэхээс гадна документ класст мөн үйлдэнэмэх хэрэгтэй. Учир нь хэрэглэгч өнгийг тодорхойлохдоо цэсийгашиглана. Иймээс цэс, тухайн үеийн өнгийг хадгалах хувьсагч, мөн өнгөнүүди йн тогтмол утгыг хадгалах массив хэлбэрийн хувьсагчшаардлагатай болно. Эдгээрийг нэмэхийн тулд

1. Class Vie асст дараах 2 хувьсагчийг нэм. w-v CLab4Doc кл

s хувьсагчийн утгуудыг Lab4Doc.cppEND_MESSAGE_MAP() const COLORREF CLab4Doc::m_crColor[8] RGB( 0, 0, 0), // Black RGB( 0, 0, 255), // Blue RGB( 0, 255, 0), // Green RGB( 0, 255, 255), // Cyan RGB( 255, 0, 0), // Red

RGB( 255, 0, 255), // Magen RGB( 255, 255, 0), // Yellow RGB( 255, 255, 255) // White }; ////////////////////////////////// // CLab4Doc construction/destruction CLab4Doc::CLab4Doc() { д OnNewDocumet, AddLineоо

доорхи байдалтай болно.

Page 29: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 29 

lor[m_nColor]);

to the object array

the

t of memory", MB_ICONSTOP | MB_OK); line object?

he exception object

4. CLa

ийг

Ca болгон өөрчил. цэс цэсийг нэм.(дарааллаар нь)

BOOL CLab4Doc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE;

alization code here // TODO: add reiniti // (SDI documents will reuse this document) m_nColor=ID_COLOR_BLACK-ID_COLOR_BLACK; return TRUE; } CLine * CLab4Doc::AddLine(CPoint ptFrom, CPoint ptTo) {

// Create a new CLine object CLine *pLine = new CLine(ptFrom, ptTo, m_crCo try { // Add the new line m_oaLines.Add(pLine); // Mark the document as dirty SetModifiedFlag(); } // Did we run into a memory exception? catch (CMemoryException* perr) {

, giving him or her // Display a message for the user // bad news AfxMessageBox("Ou // Did we create a if (pLine) {

// Delete it delete pLine;

pLine = NULL; } // Delete t perr->Delete(); } return pLine; }

b4Doc класст доорхи функцийг нэм. UINT CLab4Doc::GetColor() { return ID_COLOR_BLACK+m_nColor; }

Дээрхи ID_COLOR_BLACK хувьсагч нь шинээр нэмэх цэсний нэр юм. 5. Хэрэглэгч өнгөө тодорхойлох цэс болон түүн дээр хийгдэх

үйлдлүүдийг нэмье. 1. Resource View->Menu(Double Click)->IDR_MAINFRAME(Double

Click) 2. Гарч ирэх цэсний зохион байгуулалт дээрхи хоосон цэс

View ард байрлуул. зөөн . Түүний

цэсний 3 ption-г &Color

раах дэд 4. ColorProperty

энд даSettinObjec t g

Menu Entry ID ID_COLOR_BLACKCaption &Black

Menu Entry ID ID_COLOR_BLACKCaption B&lue

Menu Entry ID ID_COLOR_BLACKCaption &Green

Menu Entry ID ID_COLOR_BLACKCaption &Cyan

Menu Entry ID ID_COLOR_BLACKCaption &Red

Menu Entry ID ID_COLOR_BLACKCaption &Magenta

Menu Entry ID ID_COLOR_BLACKCaption &Yellow

Menu Entry ID ID_COLOR_BLACKCaption &White5. Class Wizard цонхыг нээ. CLab4Doc классыг сонго.

Page 30: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 30 

6. Нэмэгд UPDATE_COMMAND_UI event-үүд дээр фун

7. Нэмэгдсэн фуd CL

d CL

nd update UI handler code here or() == ID_COLOR_BLACK ? 1 : 0);

d CL

;

гэх мэтчилэн8.

ний

гө сонгогдсон . Энэ функц нь

хөрвүүлж ажиллагааг нь шалга. Даалга

ммд шулууны өргөн, нарийнийг лж байгаа шиг г болго. өргөнийг тодорхойлох тогтмол утгууд

ry th Settin

сэн цэснүүдийн COMMAND бакц нэм. нкцүүдэд хийгдэх үйлдэл. ab4Doc::OnColorBlack() voi

{ // TODO: Add your command handler code here

m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK; }

ab4Doc::OnUpdateColorBlack(CCmdUI* pCmdUI) voi

{ // TODO: Add your comma

pCmdUI->SetCheck(GetCol }

id CLab4Doc::OnColorBlue() vo

{ // TODO: Add your command handler code here

m_nColor=ID_COLOR_BLUE-ID_COLOR_BLACK; }

ab4Doc::OnUpdateColorBlue(CCmdUI* pCmdUI) voi

{ // TODO: Add your command update UI handler code here pCmdUI->SetCheck(GetColor() == ID_COLOR_BLUE ? 1 : 0)} бүх өнгөний цэсний функцүүдэд нэм.

Command функц нь тухайн цэсний өнгийг тодорхойлж өгөх үүрэгтэй. Үүнд хийгдэж байгаа

m_nColor=ID_COLOR_BLUE-ID_COLOR_BLACK; үйлдэл нь m_nColor хувьсагчид тухайн сонгогдсон өнгөm_crColors массив дахь индексийг олгож байна. Харин UPDATE_COMMAND_UI функцэд тухайн өнцэсийг тэмдэглэх үйлдлийг хийж байнаихэвчлэн цэсийг тэмдэглэх, идэвхтэй болгох, идэвхгүйболгох зэрэг үйлдэл хийхэд ашиглагддаг.

Программаавар: Програ өнгө тодорхой

тодорхойлдоШулууны

Menu Ent Wid gVery Thin 1Thin 8Medium 16Thick 24Very Thick 32

  

              

Page 31: Vizual programchilal cu lekts

Визу

Бол

уал програ

о

MDI ерэнӨөрөцонх

(chi Ийм CMaiшинжчанаӨнөөзохихэлбялгаШинэ

ПрогтодоStatболгДэд Прогпрогmessбид

овсруулсан

Сэдэв: программ нхий хэлбэөөр хэлбэлхтой байна

ild) цонх

программыinFrame –сж чанарыг арыг тодорөдөр бид өион байгуубэрийн проаатай. ээр MDI пр

1. ШинэDocu

2. 4-р

3. Мөн тодо

4. Прогграммдаа норхойлдог,tusBar дээгоно. Үүницэс нэмэхграммд болграммын цоsage илгээдэд цэс г1. Reso2. Шинэ3. Нэмэ

амчлал СИИ++ хичээл

н багш: Т.

MDI прогргэдэг нь эр бөгөөд л нэг ерөна. Ерөнхий

гэж нэрлэ

ыг AppWizaс удамшдагагуулсан рхойлох клөмнөх лабоулна. AppWограмм үүс

рограмм үүэ AppWizarument-г солабораторөмнөх лаборхойлдог граммаа хөнэмээд бид мөн toolэр одоогийий тулд дах. лон програонхон дээрэгддэг. Энгаргахын тource Viewээр нэмэгдэгдсэн цэс

.Уламбаяр

Leрамм үүсгэSDI прогртухайн хэнхий цонхтй цонхыг э

эдэг.

ard-р үүсгг классын класс мөнласс тус торатори дэWizard-р Mсгэхтэй ад

үсгэх rd прожектонго. ри шиг пробораторийншулуун зуөрвүүлж ажд PopupMenlbar-н тусйн идэвхтэараах алхм

аммын цонхр хулганы нэ messageтулд эхлээw->(right дсэн цэснисний зохио

лийн лекцийн хураа

р

ecture эх, програраммтай адэд хэдэн бтой ба харэцэг цонх

гэхэд SDI оронд CMDн CMDIChilтус үүсдэгээрхи шиг MDI проградил ба зөв

т (Lab5) ү

ограммаа үн ажлын даурдаг, файжиллагааг nu-н тусласламжтайгаэй байгаа муудыг гүй

хон дээр дбаруун тоe нь WM_COэд дэд цэсclick on ий ID-г IDон байгуул

ангуй

№9-10 аммд toolbдил баримтбаримтыг зрин баримтгэх ба ба

шиг олон DIMainWnd-ldWnd –с уг. үйлдэл хиамм үүсгэхвхөн эхний

үүсгээд эх

үүсгэ. арааллаар йлд хадгалнь шалга.амжтайгаараар өнгө, өнгө болойцэтгэнэ.

дэд цэс гаовч дарагдONTEXTMENUсээ лдэбэ нMenu)-> IDR_CONTEXTлалт

bar, statuт боловсрузэрэг болт болгон наримтын цо

класс үүс-с удамшсаудамшсан х

ийдэг MDI х алхмууд й алхам да

хний алхам

өнгө, өрглдаг, файл. р өнгө, өрөргөнийг он, өргөни

аргах өөрөдлаа гэдгиU юм. Энэ нэ. Үүний Insert MenTMENU болг

usbar ашигуулах прогловсруулдань тус тусонхыг хүүх

глах граммын аг. сдаа хэд

сдэг. Хариан эцэг цохүүхэд цон

applicati

ин онхны

нь үндсэн

нхны шинж

ion

ахь сонголндээ SDI лтоороо

мд Multiplle

гөнийг лаас уншда

ргөнийг

аг болго.

тодорхойлийг хардаг

өөр хэлбэл

лдог,

ийг илтгэс

г

л

мэдээллийтулд:

сэн йг ирэхэд

nu гон өөрчилл.

Page 311 

Page 32: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 32 

olor, элтэй адил байна.

лно. 6. Class Wizard->CLab5View->WM_CONTEXTMENU(add function) 7. Нэмэгдс

:OnContextMenu(CWnd* pWnd, CPoint point)

handler code here

pContextMenu->TrackPopupMenu(TPM_LEFTALIGN |

үлж ажиллагааг нь шалга. лдэл нэмэх.

гүйцэтгэх

дээр айн товчин дээрх зургийг гарч ирэх зургийн

2.2. гарган өнгийн

товчны

Member

3.1.2. tected) 3.2. л

STRUCT lpCreateStruct)

4. Энэ цэсний командуудын хийгдэх үйлдэл нь үндсэн цэсний CWidth цэсний коамндуудын хийх үйлд

5. WM_CONTEXTMENU мэдээлэл ирэхэд хийх үйлдлийг тодорхой

эн функцэд хийгдэх үйлдэл void CDay11View: {

// TODO: Add your message CMenu menu; // Load the context menu

menu.LoadMenu(IDR_CONTEXTMENU); // Get the first sub menu (the real menu)

0); CMenu *pContextMenu = menu.GetSubMenu(

// Display the context menu for the user TPM_LEFTBUTTON | TPM_RIGHTBUTTON,

d()); point.x, point.y, AfxGetMainWn}

8. Программаа хөрвү

ToolBar болон StatusBar ашиглах үйПрограммын цонхонд (эцэг) Toolbar нэмэхийн тулд дараах алхмуудыг

шаардлагатай. 1. Шинээр ToolBar үүсгэнэ.

1.1. Resource View->(right click on Toolbar)->Insert Toolbar 1.2. үүссэн ToolBar-н ID-г IDR_TBCOLOR болгон өөрчил.

2. Үүссэн ToolBar –н харагдах байдлыг өөрчилнө. 2.1. ToolBar-д зураг байхгүй хоосон товч байх ба товчин

дарснаар туххэрэгслийн самбар дээрх хэрэгслүүдийг ашиглан өөрчлөх боломжтой. Зургийг өөрчлөх агшинд ToolBar-д шинээр товч нэмэгдэнэ. Зургийг нь өөрчилсөн товчны Properties цонхыг (Alt+Enter) ID -г нь ID_COLOR_BLACK болгон сонго. (хар

хувьд).

2.3. Үүссэн ToolBar-н харагдах байдал

2.4. Өнгөнүүдийн товчны ID-г тус бүрд нь өөрчилнө. 3. Программын цонхонд үүсгэсэн Toolbar-г хавсаргах программын кодыг

нэмнэ. Үүнийг цонх үүсэх агшинд хийж өгнө. Цонх үүсэхэд дуудагддаг OnCreate функцфункц нь юм.

. Цонхонд ToolBar үүсгэхэд ашиглах хувьсагчаа зарлана. 3.13.1.1. Class view->(right click on CmainFrame)->Add

Variable Type: CToolBar, Name: m_wndColorBar, (pro

айдалтай болгон өөрчиOnCreate функцийг дараах бOnCreate(LPCREATEint CMainFrame::

{ if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

Page 33: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 33 

LYBY |

_wndToolBar.LoadToolBar(IDR_MAINFRAME))

return -1; // fail to create

T, WS_CHILD | CBRS_TOOLTIPS |

OR))

// Loop through the buttons, setting them to act as radio uttons

r.SetButtonStyle(i, TBBS_CHECKGROUP);

the toolbar

ANY); BRS_ALIGN_ANY); ;

_wndToolBar);

бар бий

тодорхойл5.1. ew ц . 5.2. үйлдэл

) != 0);

5.3. ааран цэсний тэмдэг гдсэ кцийг нэмнэ.

UI handler code here etStyle() & WS_VISIBLE) != 0 ?

1 : 0);

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FCBRS_SIZE_DYNAMIC) || !m { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) ||

ators, !m_wndStatusBar.SetIndicators(indicsizeof(indicators)/sizeof(UINT)))

{ TRACE0("Failed to create status bar\n");

} int iTBCtlID; int i; // Create the Color Toolbar

FLA if (!m_wndColorBar.CreateEx(this, TBSTYLE_ WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndColorBar.LoadToolBar(IDR_TBCOL { TRACE0("Failed to create toolbar\n");

// fail to create return -1; } // Find the Black button on the toolbar iTBCtlID = m_wndColorBar.CommandToIndex(ID_COLOR_BLACK); if (iTBCtlID >= 0) { Ab for (i= iTBCtlID; i < (iTBCtlID + 8); i++) m_wndColorBa } // TODO: Delete these three lines if you don't want to // be dockable

RS_ALIGN_ m_wndToolBar.EnableDocking(CB m_wndColorBar.EnableDocking(C

EnableDocking(CBRS_ALIGN_ANY) DockControlBar(&m // Dock the Color Toolbar DockControlBar(&m_wndColorBar); return 0; }

снээр4. Ингэ таны программд өнгөний сонголттой хэрэгслийн самболно.

5. Цэсэнд нэмэгдсэн хэрэгслийн самбарын харагдах, харагдахгүйг доiг үйлдэлтэй цэс нэмье.

V эсэнд Colorbar нэртэй шинэ дэд цэс нэмнэандыг сонгоход хийгдэхЭнэ нэмэгдсэн цэсийн ком

void CMainFrame::OnViewColorbar() { // TODO: Add your command handler code here BOOL bVisible; // Check the state of the color toolbar

tyle() & WS_VISIBLE bVisible = ((m_wndColorBar.GetS // Toggle the color bar ShowControlBar(&m_wndColorBar, !bVisible, FALSE); // Reshuffle the frame layout RecalcLayout(); }

н ColorBar –н харагдах, харагдахгүйгээс хамМөэл н эсэхийг тодорхойлно. Үүний тулд дараах фун

v d CMainFrame::OnUpdateViewColorbar(CCmdUI* pCmdUI) oi{ // TODO: Add your command update pCmdUI->SetCheck((m_wndColorBar.G

Page 34: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 34 

}

д

өгнө. Өөрөөр

7.4 а гэсэн мөрийг 2 удаа нэмнэ.

IDR_TBCOLOR TOOLBAR DISCARDABLE 16, 15 BEGIN

LOR_YELLOW LOR_WHITE

7.6. гарч ирнэ.

команды д шинэ мөр нэмнэ. Дараах мө

6. Программаа хөрвүүлж ажиллагааг нь шалга. Хэрэгслийн самбарт comboBox нэмэх

7. Цэс хэлбэрээр хийсэн шулууны өргөнийг тодорхойлох үйлдлийг слийхэрэг н самбар дээр combobox контрол ашиглан хийе. Үүний тул

дараах үйдлүүдийг хийнэ. 7.1. Visual C++ -н едитор ашиглан Toolbar-т Combobox нэмэх

ломж бид үүнийг өөрсдөө хйиж бо гүй байдаг. Иймээсхэлбэл программынхаа resource файлыг өөрчилнө.

7.2. Visual C++-с гар. 7.3. Notepad-г ажиллуулан Lab5.rc файлыг нээ.(өөрийн

программын директор дотроос) Bar хэмээх toolbar-н бичлэг. Үүнд саяын нэмэгдсэн Color

байга . Түүний ард Separator

BUTTON ID_COLOR_BLACK BUTTON ID_COLOR_BLUE

BUTTON ID_COLOR_GREEN BUTTON ID_COLOR_CYAN BUTTON ID_COLOR_RED

OLOR_MAGENTA BUTTON ID_CBUTTON ID_COBUTTON ID_COSEPARATOR SEPARATOR

END 7.5. Үүний эхнийх нь обьектын хоорондох зураас, 2 дахь нь ямар

нэгэн обьек тавих зай гэж ойлгодог. ComboBox-д сонгогдох мөрүүдийг String Table-д нэмнэ. (double click on String Table) дараах хэлбэрээр

7.7. Үүн дээр хулганы баруун товчийг товшиход гарч ирэх

цэснээс Insert String г сонгоорүүдийг нэм. ID CaptionID_WIDTH_VTHIN Very ThinID_WIDTH_THIN ThinID_WIDTH_MEDIUM MeduimID_WIDTH_THICK ThickID_WIDTH_VTHICK Very Thick

7.8. Одоо программын аргаар ComboBox-г нэмэх хэрэгтэй. Үүнийг

үүсгэнэ.

хийхийн тулд дараахалхмуудыг гүйцэтгэнэ. 7.8.1. Combobox-д ашиглах ID-г үүсгэнэ.

лдэнэ. 7.8.2. ComboBox2-г toolbar дээр үүсгэх зайг бэ8.3.7. Combobox-г Toolbar-н хүүхэд цонх байдлаар

7.8.4. ComboBox-д сонгогдох мөрүүдийг нэмнэ.

Page 35: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 35 

тусад нь функц үүсгэе. (BOOL

7.11. лдэл ar()

iTBCtlID;

Y |

)

rBar.CommandToIndex(ID_COLOR_BLACK);

Bar.SetButtonStyle(i, TBBS_CHECKGROUP);

9, IDC_CBWIDTH, TBBS_SEPARATOR,nWidth);

; nHeight;

t, &m_wndColorBar, IDC_CBWIDTH);

.AddString((LPCTSTR)szStyle);

ource View->Right click on Lab4 Resources->Resource

х хэсгийг тусад нь авсан учраас OnCreate функц нь

(lpCreateStruct) == -1)

D |

))

); turn -1; // fail to create

7.9. Дээрх үйлдлийг хийсэн программын кодыг нэмье. 7.10. Хялбарчилахын тулд

CMainFrame::CreateColorBar()) Нэмэгдсэн функцэд хийгдэх үйBOOL CMainFrame::CreateColorB{

int int i; if (!m_wndColorBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYB

IZE_DYNAMIC) || CBRS_S !m_wndColorBar.LoadToolBar(IDR_TBCOLOR) {

TRACE0("Failed to create toolbar\n"); return FALSE; // fail to create }

BCtlID = m_wndColo iT if (iTBCtlID >= 0) {

for (i= iTBCtlID; i < (iTBCtlID + 8); i++) m_wndColor } // Add the Combo

int nWidth = 100; int nHeight = 125;

// Configure the combo place holder m_wndColorBar.SetButtonInfo( // Get the colorbar height CRect rect; m_wndColorBar.GetItemRect(9, &rect)

rect.bottom = rect.top + // Create the combo box m_ctlWidth.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL |

CBS_DROPDOWNLIST, rec // Fill the combo box CString szStyle;

if (szStyle.LoadString(IDS_WIDTH_VTHIN)) m_ctlWidth.AddString((LPCTSTR)szStyle); if (szStyle.LoadString(IDS_WIDTH_THIN))

m_ctlWidth.AddString((LPCTSTR)szStyle); if (szStyle.LoadString(IDS_WIDTH_MEDIUM)) m_ctlWidth.AddString((LPCTSTR)szStyle); if (szStyle.LoadString(IDS_WIDTH_THICK)) m_ctlWidth.AddString((LPCTSTR)szStyle); if (szStyle.LoadString(IDS_WIDTH_VTHICK))

m_ctlWidth return TRUE; }

7.12. Үүнд ашиглагдаж байгаа IDC_CBWIDTH нь combobox-н ID юм. Үүнийг дараах байдлааг нэмнэ.

7.13. ResbolSym s

7.14. New-> Name: IDC_CBWIDTH 8. ColorBar үүсгэ

өөрчлөгдөнө. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {

FrameWnd::OnCreate if (CMDI return -1;

f (!m_w i ndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILWS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |

C) || CBRS_SIZE_DYNAMI !m_wndToolBar.LoadToolBar(IDR_MAINFRAME {

RACE0("Failed to create toolbar\n" T re

Page 36: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 36 

}

_ANY);

dth

if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) {

\n"); TRACE0("Failed to create status barl to create return -1; // fai

} if (!CreateColorBar()) {

bar\n"); TRACE0("Failed to create color tool return -1; // fail to create

} // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); m_wndColorBar.EnableDocking(CBRS_ALIGN EnableDocking(CBRS_ALIGN_ANY);

; DockControlBar(&m_wndToolBar) // Dock the Color Toolbar

dColorBar); DockControlBar(&m_wn return 0; }

ахад ComboBox нэмэгдсэн нь харагдана. 9. Программа ажиллуулComboB үox-н йлдлийг нэмэх.

10. ComboBox-н сонголт өөрчлөгдсөн хэмээх event нь ON_CBN_SELCHANGE эм хэд дуудагдах функцийг нэмнэ. х ээх утга байдаг. Энэ Event-г илрэ

11. дэл Нэмэгдсэн функцэд хийгдэх үйлd CMavoi inFrame::OnSelChangeWidth()

{ // Get the new combo selection

.GetCurSel(); int nIndex = m_ctlWidth CB_ERR) if (nIndex ==

return; // Get the active document

)GetActiveDocument(); CToolbarDoc* pDoc = (CToolbarDoc*ve a valid document? // Do we ha

if (pDoc) // Set the new drawing wi pDoc->SetWidth(nIndex); }

12. Харин нэмсэн функцээ Event-тэй холбохдоо CMainFrame классын messagemap-д дараах өөрчлөлтийг хийнэ.

/////////////////////////////////////////////////////////////////////////////

CMainFrame // IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_COMMAND(ID_VIEW_COLORBAR, OnViewColorbar) ON_UPDATE_COMMAND_UI(ID_VIEW_COLORBAR, OnUpdateViewColorbar) //}}AFX_MSG_MAP ON_CBN_SELCHANGE(IDC_CBWIDTH, OnSelChangeWidth) END_MESSAGE_MAP()

13. Нэмэгдсэн функц дэх SetWidth функц нь баримтын шулууны өргөнийг өр . ө члөх функц юм. Иймээс дээрхи функцийг нэм

14. Программаа хөрвүүлж ажиллагааг шалга. Status Bar ашиглах

15. StatusBar нь индикаторууд хэмээх текст мэдээлэл илэрхийлэх хэсгүүдээс тогтдог. Программист мэдээллийн самбар дээр өөрийн мэдээллийн гаргах индикатор хэсгийн нэмэх боломжтой. Үүнийг роп граммд зарласан байдаг.

16. ям мье. Бид ар өнгө сонгогдсоныг илтгэдэг индикатор шинээр нэ16.1. String Table-д индикаторын ID-г Caption-г өгнө.

_IN(ID DICATOR_COLOR) 16.2. Индикаторуудын зарлалтанд нэмсэн индикаторыг нэмнэ.

Page 37: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 37 

////////////////////////////////////////////////////////

rbar)

HANGE(IDC_CBWIDTH, OnSelChangeWidth)

status line indicator

mdUI *pCmdUI) нэртэй

torColor(CCmdUI *pCmdUI)

nt color?

K";

A";

/ White

s bar pane

16.5. Нэмэгд г нэм.

lorCyan)

///////////////////// // CMainFrame IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_COMMAND(ID_VIEW_COLORBAR, OnViewColorbar) ON_UPDATE_COMMAND_UI(ID_VIEW_COLORBAR, OnUpdateViewColo

_MAP //}}AFX_MSGON_CBN_SELC

END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // ID_INDICATOR_COLOR, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, };

16.3. Программыг хөрвүүлэн ажиллуулахад индикатор нэмэгдэх боловч дээрх мэдээлэл нь гарахгүй. Үүнийг гаргахын тулд

ндаста рт event-г ашиглана. Өөрөөр хэлбэл тухайн индикаторыг дахин сэргээхэд өнгөний тухай мэдээллийг гаргадаг функц нэмнэ.

16.4. Шинээр afx_msg void төрлийн OnUpdateIndicatorColor(CC функцийг документ класст нэм.

void CToolbarsDoc::OnUpdateIndica{ CString strColor; // What is the curre switch (m_nColor) {

/ Black case 0: / strColor = "BLAC break; case 1: // Blue strColor = "BLUE"; break; case 2: // Green strColor = "GREEN"; break;

case 3: // Cyan strColor = "CYAN"; break; case 4: // Red strColor = "RED"; break;

/ Magenta case 5: / strColor = "MAGENT break;

/ Yellow case 6: / strColor = "YELLOW"; break; case 7: / strColor = "WHITE"; break; } // Enable the status bar pane pCmdUI->Enable(TRUE); // Set the text of the statu // to the current color pCmdUI->SetText(strColor); } сэн функцийн Event гарч ирэхэд дуудах үйлдлийBEGIN_MESSAGE_MAP(CToolbarsDoc, CDocument) ON_UPDATE_COMMAND_UI(ID_INDICATOR_COLOR, OnUpdateIndicatorColor) //{{AFX_MSG_MAP(CToolbarsDoc) ON_COMMAND(ID_COLOR_BLACK, OnColorBlack) ON_UPDATE_COMMAND_UI(ID_COLOR_BLACK, OnUpdateColorBlack) ON_COMMAND(ID_COLOR_BLUE, OnColorBlue)

_BLUE, OnUpdateColorBlue) ON_UPDATE_COMMAND_UI(ID_COLOR ON_COMMAND(ID_COLOR_CYAN, OnCo. . .

Page 38: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 38 

ограммаа хөрвүүлж ажиллагааг нь шалга.

индикатор нэм.

17. ПрДаалгавар.

Цэсээр шулууны өргөн солигдо1. ход ComboBox дахь сонголт мөн өөрчлөгддөг байх хэрэгтэй.

2. StatusBar дээр шулууны өргөний байдлыг текстээр илэрхийлдэг

                                            

Page 39: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 39 

 

в а

BC –д тодорхойлогдсон өгөгдлийн санг

лхээний төрөл. Доохи хэлхээний

Lecture №11-12 Сэдэ : Өгөгдлийн сантай жиллах

Ихэнх программууд өгөгдлийн сантай ажиллах үйлдэлтэй байдаг. Өгөгдлийн сан нь PC based, Shared гэсэн 2 төрлийн байдаг. PC based гэдэг нь нэг компьютер дээр байх ба ийм өгөгдлийн санг Microsoft-н Access, FoxProба Borland-н Paradox дээр үүсгэдэг. Харин Shared өгөгдлийн сан нь SQL хэлбэр дээр тулгуурладаг ба үүнийг SQL (Structured Query Language) server эсвэл Oracle дээр зохион байгуулдаг. Гэвч бүх өгөгдлийн санд адил өгөгдлийн бичлэгүүдэд боловсруулалт хийх үйлдлүүд байдаг. Эдгээр нь бичлэгүүдийг сэргээх, устгах, өөрчлөх зэрэг үйлдлүүд юм. Энэ үйлдлүүд адил боловч өгөгдлийн санг программдаа ашиглаж байгаа холбоос нь өөр өөр байдаг. Бид өнөөдөр ODBC (Open Database Connector) холбоосыг хэрхэн ашиглах талаар үзнэ. ODBC нь өгөгдлийн сан болгонд төрлөөс нь хамаарч программд холбох өөр өөрийн технологи буюу driver программ байдаг гэж үздэг. Visual C++ хэлд өгөгдлийн сантай холбох обьектууд нь CRecordset, CDatabase классууд юм. CDatabase класс нь өгөгдлийн сантай холбох бүх мэдээллийг агуулах ба программын бүх хэсгүүдэд ашиглах боломжтой байдаг. Харин CRecordset класс нь өгөгдлийн сан дахь бичлэгүүдийн хэлхээг агуулах ба программын явцад бичлэгт хийсэн өөрчлөлтийг цааш нь өгөгдлийн санд хадгалах үргийг гүйцэтгэдэг. AppWizard нь ODүпрограммд оруулах үйдлийг агуулдаг. Бичлэгүүдийн хэлхээг нээх болон хаах. CRecordset обьект нэгэнд үүсээд өгөгдлийн сантай холбогдсон бол өгөгдлийн сан дахь бичлэгүүдийн хэлхээнүүдээс программд ашиглах өөрийн бичлэгүүдийн хэлхээг нээнэ. Үүнийг CRecordset обьектын Open гишүүн функцын тусламжтайгаар хийнэ. Энэ функцыг аргументгүйгээр дуудвал параметрүүдийг стандарт утгаар нь дуудсантай адил.

ишүүн функцын эхни ент бол бичлэгүүдийн хэOpen гхүснэгт

й аргумэй бичлэгүүдийн

Төрөл төрлүүдийг харуулав.

ТайлбарCRecordset::dynaset Бичлэгүүдийн хэлхээ нь Fetch функцыг дуудсанаар

сэргээгдэх боломжтой ба хэлхээнд өөр хэрэглэгчийн хийсэн өөрчлөлтийг харах боломжтой.

CRecordset::snapshot Хэлхээ нь хаагдаж дахинй

онгойлгохоос нааш сэргээгдэх боломжгү

CRecordset::dynamic ODBC драйверт боломжгүйCRecordset::forwardOnly

Хэлхээг зөвхөн унших ба эхний бичлэгээс сүүлийбичлэг хүртэл гүйлгэж харах боломжтой.

н

2 дахь аргумент бол бичлэгүүдийн хэлхээнд хийгдэх үйлдлийн төрөл. Хэрэв NULL бол AppWizard-д заагдсан утгаар стандарт утгаа авна. 3 дахь аргумент бол бичлэгүүдийн хэлхээг өгөгдлийн сан дахь бичлэгүүдтэй

тухай мхэрхэн уялдуулах эдээлэл байдаг. Өргөн хэрэглэгддэг зарим утгуудыг доор хүснэгтэд үзүүлэв. CRecordset::none Бичлэгүүдийн хэлхээнд хийгдэх үйлдэл тодорхойгүй.CRecordset::appendOnly а өгөгдөл устгах, Хэлхээнд зөвхөн өгөгдөл нэмэх б

өөрчлөх боломжгүй. CRecordset::readOnly Хэлхээнээс зөвхөн өгөгдөл уншина. Нэгэнт хэрэглэгч өгөгдлийн сантай ажиллаж дууссан бол CRecordset обьектыг хаах хэрэгтэй. Үүнийг Close функцыг дуудаж хийнэ. Энэ функц нь аргум

й. ент

лхээнд заагчи в. байхгүНээлттэй хэ йг үлэх үйлдлийг доорхи хүснэгтэй үзүүлэшилжүФункц ТайлбарMoveFirst Хэлхээний эхний бичлэгэд заагчийг шилжүүлнэ.MoveLast Хэлхээний ссүлийн бичлэгэд заагчийг шилжүүлнэ.MoveNext Дараагийн бичлэгэд заагчийг шилжүүлнэ. MovePrev Өмнөх бичлэгэд заагчийг шилжүүлнэ. Move Одоогийн бичлэгээс эсвэл

байрлал дахь бичлэгт заагчийэхний бичлэгээс заагдсан г шилжүүлнэ.

SetAbsolutePosition Заагдсан бичлэгт шилжүүлнэ.

Page 40: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 40 

IsBOF Заагч эхний бичлэг дээр байвал TRUE утга буцаанаIsEOF Заагч сүүлийн бичлэг дээр байвал TRUE утга буцаанаGetRecordCount Хэлхээн дэх бичлэгийн тооДээрхи Move функц нь 2 аргузаана. 2 дахь аргумент нь хэ

менттай ба эхний аргумент нь шилжих мөрийн тоог заана.

д хийгдэх үндсэн байдаг

рхэн шилжихийгХэлхээнд хийгдэх үйлдлүүд. Хэлхээн үйлдлүүдФункц ТайлбарAddNew Шинэ бичлэг нэмнэDelete Идэвхтэй бичлэгийг устганаEdit Идэвхтэй бичлэгийг зөсвөр хийх горимд оруулна.Update Өгөгдлийн санд хийгдсэн үйлдлийг хадгална. Requery Хэлхээг сэргээнэ. Программ үүсгэх. Программын урсгалыг үүсгэхээс өмнө биүүсгэж ODBC-д оруулах хэрэгтэй.

д программд ашиглах өгөгдлийн санг

1.4. My Documents folder-т Address нэртэйгээр хадгал.

бэлдэж ODBC

2.1. Control Panel->ODBC Data Sources (ODBC Administrator)

1. Өгөгдлийн санг Access ашиглан үүсгэ 1.1. Microsoft Access-г ажиллуул. 1.2. Database Wizard-г сонгоод Ok товч дар. 1.3. Address Book template-г сонго.

1.5. Дээрхи байдлаар сонгоод Finish товчийг дарж өгөгдлийн санг үүсгэ. 1.6. Өгөгдлийн сан үүссэн бол Access-г хаа.

2. Нэгэнт өгөгдлийн сан үүссэн бол үүнийг программд ашиглахадdata source-г үүсгэх хэрэгтэй.

Page 41: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 41 

2.2. Шинээр data Source үүсгэ (Add …)

2.3. Microsoft Access Driver –г сонгоод Finish товчийг дарахад дараах цонх гарч ирнэ. Data Source Name – MyAccess гэж өгөөд Select товчийг дарж өмнө үүсгэсэн өгөгдлийн санг зааж өгнө.

Page 42: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 42 

2.4. Ok товчуудыг даран data source-г үүсгэсэн бол ODBC administrator-

г хаа. 3. Өнөөдөр бид жишээ программаа SDI хэлбэрээр үүсгэнэ. SDI программ үүсгэх

2 дахь алхамд Database view with file support сонголтыг сонгоод Data Source товчийг дарж гарч ирэх цонхон дээрээс ODBC –г сонгон үүсгэсэн data source-г сонгоно. Төрлийг dynaset, snapshot аль нэг нь байна.

4. Ok товч дарахад гарч ирэх цонхноос Addresses table-г сонгоод OK товчийг дар.

5. AppWizard-н дараагийн алхмуудын утгыг хэвээр нь үлдээгээд явахад сүүлийн алхамд View класс нь CRecordView классаас удамшин гарсныг харна. Энэ нь үндсэндээ CFormView классаас удамшсан бөгөөд харин өгөгдлийн сантай ажиллах зарим үйлдлүүдийг нэмсэн класс юм.

6. Программын цонхны харагдах байдлыг өөрчил. Static Text ID IDC_STATIC Caption ID: Edit Box ID IDC_EID Static Text ID IDC_STATIC Caption First Name: Edit Box ID IDC_EFNAME Static Text ID IDC_STATIC Caption Last Name: Edit Box ID IDC_ELNAME Static Text ID IDC_STATIC Caption Spouse Name: Edit Box ID IDC_ESNAME Static Text ID IDC_STATIC Caption Address: Edit Box ID IDC_EADDR Multiline Checked Static Text ID IDC_STATIC Caption City: Edit Box ID IDC_ECITY Static Text ID IDC_STATIC Caption State: Edit Box ID IDC_ESTATE Static Text ID IDC_STATIC Caption Zip: Edit Box ID IDC_EZIP Static Text ID IDC_STATIC Caption Country: Edit Box ID IDC_ECOUNTRY Static Text ID IDC_STATIC Caption E-Mail: Edit Box ID IDC_EEMAIL

Page 43: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 43 

Static Text ID IDC_STATIC Caption Home Phone: Edit Box ID IDC_EHPHONE Static Text ID IDC_STATIC Caption Work Phone: Edit Box ID IDC_EWPHONE Static Text ID IDC_STATIC Caption Extension: Edit Box ID IDC_EWEXT Static Text ID IDC_STATIC Caption Fax: Edit Box ID IDC_EFAX Static Text ID IDC_STATIC Caption Birthdate: Edit Box ID IDC_EDOB Check Box ID IDC_CBCARD Caption Send Card Static Text ID IDC_STATIC Caption Notes: Edit Box ID IDC_ENOTES Multiline Checked

7. Программд ашиглах хувьсагчуудыг контролуудад хавсаргана. Өгөгдлийн

сангийн тухайн талбарын өгөгдлийг ашиглах контролд хувьсагчийг бичлэгийн хэлхээний талбарын нэрийг шууд өгөх боломжтой байдаг. Өөрөөр хэлбэл View обьектод автоматаар зарлагдсан m_pSet хувьсагчийн гишүүн хувьсагчуудыг өгнө. Ийм хувьсагчийг нэмэхдээ хувьсагч нэмэх цонхны хувьсагчийн нэр бичих ComboBox-с нэрийг сонгоно.

Page 44: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 44 

8. Контролуудад доорхи хувьсагчдыг хавсарга. Контрол Хувьсагчийн нэрIDC_CBCARD m_pSet->m_SendCardIDC_EADDR m_pSet->m_AddressIDC_ECITY m_pSet->m_CityIDC_ECOUNTRY m_pSet->m_CountryIDC_EEMAIL m_pSet->m_EmailAddressIDC_EFAX m_pSet->m_FaxNumberIDC_EFNAME m_pSet->m_FirstNameIDC_EHPHONE m_pSet->m_HomePhoneIDC_EID m_pSet->m_AddressIDIDC_ELNAME m_pSet->m_LastNameIDC_ENOTES m_pSet->m_NotesIDC_ESNAME m_pSet->m_SpouseNameIDC_ESTATE m_pSet->m_StateOrProvinceIDC_EWEXT m_pSet->m_WorkExtensionIDC_EWPHONE m_pSet->m_WorkPhoneIDC_EZIP m_pSet->m_PostalCode9. Хувьсагч хавсаргахад он сар болон цаг.минут төрлийн хувьсагчид алдаа

гарч болно. Учир нь Visual C++ CTime төрлийн хувьсагчид 1969 оноос өмнөх утгыг хадгалах боломжгүйгээр хийгдсэн байдаг. Мөн контролд хавсаргах боломжгүй байдаг. Үүнийг шийдэхийн тулд CTime төрлийн хувьсагчийг COleDateTime болгон засч өгөх хэрэгтэй. Мөн хийгдэж байгаа үйлдлүүдийг үүнд зохицуулан өөрчлөлт хийх хэрэгтэй. Өөрөөр хэлбэл бид өөрсдөө контролд хавсаргах бичлэгийг хийж өгнө. IDC_EDOB контролд COleDateTime төрөлтэй m_oledtDOB нэртэй хувьсагч хавсаргаж нэм. Бидний программд дээрх алдааг засахын тулд дараах хэсгүүдийг өөрчилнө. 9.1. dbodbcSet класс дахь зарлалтыг дараах байдалтай болгон өөрчилнө.

Field/Param Data //{{AFX_FIELD(CDbodbcSet, CRecordset) long m_AddressID; CString m_FirstName; CString m_LastName; CString m_SpouseName; CString m_Address; CString m_City; CString m_StateOrProvince; CString m_PostalCode; CString m_Country; CString m_EmailAddress; CString m_HomePhone; CString m_WorkPhone; CString m_WorkExtension; CString m_FaxNumber; COleDateTime m_Birthdate; BOOL m_SendCard; CString m_Notes; //}}AFX_FIELD

Page 45: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 45 

9.2. View классын DoDataExchange функцэд дараах байдалтай болгон үйлдэл нэмнэ.

void CDbodbcView::DoDataExchange(CDataExchange* pDX) { CRecordView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDbodbcView) DDX_FieldCheck(pDX, IDC_CBCARD, m_pSet->m_SendCard, m_pSet); DDX_FieldText(pDX, IDC_EADDR, m_pSet->m_Address, m_pSet); DDX_FieldText(pDX, IDC_ECITY, m_pSet->m_City, m_pSet); DDX_FieldText(pDX, IDC_ECOUNTRY, m_pSet->m_Country, m_pSet); DDX_FieldText(pDX, IDC_EEMAIL, m_pSet->m_EmailAddress, m_pSet); DDX_FieldText(pDX, IDC_EFAX, m_pSet->m_FaxNumber, m_pSet); DDX_FieldText(pDX, IDC_EFNAME, m_pSet->m_FirstName, m_pSet); DDX_FieldText(pDX, IDC_EHPHONE, m_pSet->m_HomePhone, m_pSet); DDX_FieldText(pDX, IDC_EID, m_pSet->m_AddressID, m_pSet); DDX_FieldText(pDX, IDC_ELNAME, m_pSet->m_LastName, m_pSet); DDX_FieldText(pDX, IDC_ENOTES, m_pSet->m_Notes, m_pSet); DDX_FieldText(pDX, IDC_ESNAME, m_pSet->m_SpouseName, m_pSet); DDX_FieldText(pDX, IDC_ESTATE, m_pSet->m_StateOrProvince, m_pSet); DDX_FieldText(pDX, IDC_EWEXT, m_pSet->m_WorkExtension, m_pSet); DDX_FieldText(pDX, IDC_EWPHONE, m_pSet->m_WorkPhone, m_pSet); DDX_FieldText(pDX, IDC_EZIP, m_pSet->m_PostalCode, m_pSet); DDX_Text(pDX,IDC_EDOB, m_oletDOB); //}}AFX_DATA_MAP if (pDX->m_bSaveAndValidate==TRUE) m_pSet->m_Birthdate=m_oledtDOB; }

9.3. Set классын конструктор функцыг өөрчилнө. CDbodbcSet::CDbodbcSet(CDatabase* pdb) : CRecordset(pdb) { //{{AFX_FIELD_INIT(CDbodbcSet) m_AddressID = 0; m_FirstName = _T(""); m_LastName = _T(""); m_SpouseName = _T(""); m_Address = _T(""); m_City = _T(""); m_StateOrProvince = _T(""); m_PostalCode = _T(""); m_Country = _T(""); m_EmailAddress = _T(""); m_HomePhone = _T(""); m_WorkPhone = _T(""); m_WorkExtension = _T(""); m_FaxNumber = _T(""); //m_Birthdate = 0; m_SendCard = FALSE; m_Notes = _T(""); m_nFields = 17; //}}AFX_FIELD_INIT m_nDefaultType = snapshot; }

10. Программаа хөрвүүлж ажиллагааг нь шалгахад программ өгөгдлүүдэд засвар ийг шилжүүлж байгаа нь харагдаж байна. хийж, одоогийн бичлэгШинээр бичлэг нэмэх. Хэдхэн үйлдэл нэмснээр программд

шинээр бичлэг нэмэх үйлдлийг хийх боломжтой. Шинээр бичлэг нэмэхийн тулд өгөгдлийн сан дахь түлхүүр талбаруудыг

анхаарч сайн зохицуулах хэрэгтэй. Бидний программд түлхүүр талбар нь AddressID гэсэн талбар бөгөөд шинээр бичлэг

нэмэхэд энэ талбарын утгыг өмнөх бичлэгүүд дэх утгуудтай давхцахгүй өөрөөр хэлбэл хамгийн сүүлийн бичлэг дэх утгыг нэгээр нэмэгдүүлж утгыг нь олгох хэрэгтэй. Үүний тулд

доорхи функцыг нэмнэ. long CDbodbcSet::GetMaxID() { MoveLast(); return m_AddressID; }

11. Шинээр бичлэг нэмэх үйлдлийг хийх цэс нэмье. Цэсийг Record цэсэнд нэмнэ.

Page 46: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 46 

Menu Entry ID IDM_RECORD_NEW Caption N&ew Record Prompt Add a new record\n New Record 12. Нэмэгдсэн цэсэнд хийгдэх үйлдэл

void CDbodbcView::OnRecordNew() { // TODO: Add your command handler code here // Get a pointer to the record set CRecordset* pSet = OnGetRecordset(); // Make sure that any changes to the current record // have been saved if (pSet->CanUpdate() && !pSet->IsDeleted()) { pSet->Edit(); if (!UpdateData()) return; pSet->Update(); } // Get the ID for the new record long m_lNewID = m_pSet->GetMaxID() + 1; // Add the new record m_pSet->AddNew(); // Set the ID in the new record m_pSet->m_AddressID = m_lNewID; // Save the new record m_pSet->Update(); // Refresh the record set m_pSet->Requery(); // Move to the new record m_pSet->MoveLast(); // Update the form UpdateData(FALSE); }

13. Toolbar-т шинэБичлэг устгах. Өгөгдлийн сантай ажилладаг программ болгонд бичлэг устгах үйлдэл байдаг. Бидний программд одоогийн идэвхтэй бичлэгийг устгаад бичлэгийн заагчийг өмнөх

бичлэгт шилжүүлдэг үйлдэлтэй цэс нэмнэ.

эр өгөгдөл нэмдэг товч нэм. Үйлдлийг нь бич.

14. Бичэг устгах цэсийг Record цэсэнд нэм. Menu Entry ID IDM_RECORD_DELETE Caption &Delete Record Prompt Delete the current record\n Delete Record15. Нэмэгдсэн цэсэнд хийгдэх үйлдэл

void CDbodbcView::OnRecordDelete() { // Make sure the user wants to delete this record if (MessageBox("Are you sure you want to delete this record?", "Delete this record?", MB_YESNO | MB_ICONQUESTION) ==IDYES) { // Delete the record m_pSet->Delete(); // Move to the previous record m_pSet->MovePrev(); // Update the form UpdateData(FALSE); } }

16. Мөн Toolbar-т бичлэг устга үйлдлийг нь нэм. даг товч нэмжДаалгавар

Record цэсэнд MoveTo цэс шинээр нэм. Уг цэсний командаар хэрэглэгчээс бичлэгийн дугаар авдаг цонх гарч ирэх ба Ok товч дарахад тухайн дугаарын бичлэгт шилждэг үйлдэл нэм.        

Page 47: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 47 

Lecture №13-14 Сэдэв: MultiThread, Multitasking Application

Өнөөдөр бид multithread application-ы энгийн жишээ болгон SDI хэлбэрийн программ дээр тус тусын thread-р ажиллах эргэлдэх өнгийн шулуунуудыг хэрхэн зохион байгуулахын авч үзнэ. Thread-н энгийн хэлбэр болох программын өөрийн урсгалыг ашиглах, нэг функц ашиглах хоёрыг ашиглан 4 эргэлдэгч шулуун үүсгэнэ. Үүний тулд программд 4 checkbox байх бөгөөд 2 нь программын урсгалаар эргэлдэх 2 шулууныг, нөгөө 2 нь хэрэглэгчийн үүсгэснээр эргэлдэх 2 шулууныг тус тус удирдана.

Программын урсгалыг үүсгэх 1. SDI applicationүүсгэ. Программын нэрийг Tasking гэж өг. 2. View класс нь CFormView-с удамшин гарах ёстой. 3. Доорхи контролуудыг программын цонхонд байрлуул Object Property Setting Check Box ID IDC_CBONIDLE1 Caption On &Idle Thread 1Check Box ID IDC_CBTHREAD1 Caption Thread &1 Check Box ID IDC_CBONIDLE2 Caption On Idle &Thread 2Check Box ID IDC_CBTHREAD2 Caption Thread &2 4. Программын цонхны харагдах байдал

5. Программын контролуудад доорхи хувьсагчдыг хавсарга. Object Name Category Type IDC_CBONIDLE1 m_bOnIdle1 Value BOOL IDC_CBONIDLE2 m_bOnIdle2 Value BOOL IDC_CBTHREAD1 m_bThread1 Value BOOL IDC_CBTHREAD2 m_bThread2 Value BOOL 6. Эргэлдэгч шулуунуудыг үүсгэхийн тулд ерөнхийд нь нэг класс авч ашиглая.

Энэ классаа thread болгон дээрээ дуудаж шулуунаа эргэлдүүлэх болно. Өөрөөр хэлбэл эргэлдэгч 4 шулуун нь нэг классын хувьсагчид байна. Шинээр үүсгэх класс нь дараагийн шулуун нь хаана зурагдахыг өөрөө тооцоолон программын цонхон дээр зурах бөгөөд мөн өнгөө өөрчилнө. Үүний тулд программын цонхны DC заагч хэрэгтэй.

7. CSpinner нэртэй CObject классаас удамшин гарсан класс шинээр нэм. 8. Шинээр үүсгэсэн класстаа дараах хувьсагчдыг нэмэх шаардлагатай.

8.1. Одоогийн өнгө (int m_crColor) 8.2. Эргэлдэгч шулууны байрлал (int m_iMinute) 8.3. Эргэлтийн радиус (int m_iRadius) 8.4. Эргэлтийн төвийн цэг (CPoint m_pCenter)

Page 48: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 48 

8.5. Шулууны өнгийн хүснэгт (static COLORREF m_crColors[8]) 8.6. View обьектын заагч (CWnd* m_pViewWnd) 8.7. Шулуун эргэлдэж буй эсэх (BOOL* m_bContinue)

9. Хувьсагчдаа нэмсэн бол классын үүсгэгч функцэд доорхи үйлдлийг хийнэ CSpinner::CSpinner() { m_iRadius = 0; m_nMinute = 0; m_crColor = 0; m_pViewWnd = NULL; m_bContinue = NULL; }

10. Мөн класстаа дараах хэдэн inline функцүүдийг нэмбэл классын зарлалт дараах байдалтай болно.

class CSpinner : public CObject { public: BOOL* GetContinue() {return m_bContinue;} void SetContinue(BOOL* bContinue) { m_bContinue = bContinue;} CWnd* GetViewWnd() { return m_pViewWnd;} void SetViewWnd(CWnd* pWnd) { m_pViewWnd = pWnd;} void SetLength(int iLength) { m_iRadius = iLength;} void SetPoint(CPoint pPoint) { m_pCenter = pPoint;} CSpinner(); virtual ~CSpinner(); private: BOOL* m_bContinue; CWnd* m_pViewWnd; static COLORREF m_crColors[8]; int m_iRadius; CPoint m_pCenter; int m_nMinute; int m_crColor; };

11. Шаардлагатай хувьсагчдын анхны утгыг олгох, утгыг өөрчлөх зэрэг функцүүдийг нэмсэн бол шулууны өнгийг тодорхойлох хүснэгтийн утгыг олгох хэрэгтэй.

static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif COLORREF CSpinner::m_crColors[8] = { RGB( 0, 0, 0), // Black RGB( 0, 0, 255), // Blue RGB( 0, 255, 0), // Green RGB( 0, 255, 255), // Cyan RGB( 255, 0, 0), // Red RGB( 255, 0, 255), // Magenta RGB( 255, 255, 0), // Yellow RGB( 255, 255, 255) // White }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CSpinner::CSpinner() { m_iRadius = 0; m_nMinute = 0;

12. Одоо шулууныг эргэлдүүлэх функцыг зохион байгуулах хэрэгтэй. Өөрөөр хэлбэл дуудагдах болгондоо шулууныг дараагийн байрлалд нь зурах функцыг зохион байгуулна. (void Draw();)

13. Уг функц нь шулууныг төвийн цэгээс захын цэг рүү, одоогийн өнгөтэй Pen-г үүсгэн зурах бөгөөд шулуун зурагдсан бол хуучин Pen-г сэргээгээд гарахаасаа өмнө дараагийн шулууны байрлалыг тооцоолоод гарна. Мөн өнгийг солих үйлдлийг хийнэ. Ингээд функц нь дараах байдалтай байна.

void CSpinner::Draw() { CDC *pDC = m_pViewWnd->GetDC(); pDC->SetMapMode (MM_LOENGLISH); CPoint org = m_pCenter; CPoint pStartPoint; pStartPoint.x = (m_iRadius / 2); pStartPoint.y = (m_iRadius / 2);

Page 49: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 49 

org.x = m_pCenter.x + (m_iRadius / 2); org.y = m_pCenter.y + m_iRadius; pDC->SetViewportOrg(org.x, org.y); CPoint pEndPoint; double nRadians = (double) (m_nMinute * 6) * 0.017453292; pEndPoint.x = (int) (m_iRadius * sin(nRadians)); pEndPoint.y = (int) (m_iRadius * cos(nRadians)); CPen pen(PS_SOLID, 0, m_crColors[m_crColor]); CPen* pOldPen = pDC->SelectObject(&pen); pDC->MoveTo (pEndPoint); pDC->LineTo (pStartPoint); pDC->SelectObject(&pOldPen); m_pViewWnd->ReleaseDC(pDC); if (++m_nMinute == 60) { m_nMinute = 0; if (++m_crColor == 8) m_crColor = 0; } }

14. Дээрхи үйлдлийг хи рхойлох шаардлагатай. йхэд math.h толгой файлыг тодоSpinner-үүдийг ашиглах

15. Spinner классыг үүсгэсний дараа үүнийг программд ашиглах, программын цонхон дээр эргэлдүүлдэх кодыг хийж өгөх шаардлагатай. Document класст private хандалттай m_cSpin[4] нэртэй CSpinner төрлийн хувьсагч нэм.

16. TaskingDoc.cpp файлд Spinner.h файлын зарлалтыг нэм. 17. Хамгийн эхний авах шаардлагатай арга хэмжээ бол эргэлдэгч шулуунуудын

эхний байрлалыг тооцоолох явдал юм. Өөрөөр хэлбэл тухайн Spinner-н массивын индексээр байрлах байрлалыг нь олох тооцоолох хэрэг юм. CtaskingDoc класст доорхи функцыг нэм.

void CTaskingDoc::CalcPoint(int nID, CSpinner *pSpin) { RECT lWndRect; CPoint pPos; int iLength; CTaskingView *pWnd; pWnd = (CTaskingView*)pSpin->GetViewWnd(); pWnd->GetClientRect(&lWndRect); iLength = lWndRect.right / 6; switch (nID) { case 0: // Position the first spinner pPos.x = (lWndRect.right / 4) - iLength; pPos.y = (lWndRect.bottom / 4) - iLength; break; case 1: // Position the second spinner pPos.x = ((lWndRect.right / 4) * 3) - iLength; pPos.y = (lWndRect.bottom / 4) - iLength; break; case 2: // Position the third spinner pPos.x = (lWndRect.right / 4) - iLength; pPos.y = ((lWndRect.bottom / 4) * 3) - (iLength * 1.25); break; case 3: // Position the fourth spinner pPos.x = ((lWndRect.right / 4) * 3) - iLength; pPos.y = ((lWndRect.bottom / 4) * 3) - (iLength * 1.25); break; } pSpin->SetLength(iLength); pSpin->SetPoint(pPos); }

18. Ингээд эргэлдэгч шулуунуудыг программд ашиглахад тэдгээрийн анхны утгуудыг зөв олгох мөн checkbox-ууд дахь тэмдэглэгээ өөрчлөгдөхөд төлөв байдлыг зохицуулах шаардлагатай. Үүний тулд доорхи функцыг нэмж ашиглая. (0,2-р spinner-үүд нь программын урсгалаар, 1,3-рх нь хэрэглэгчийн үүсгэсэн thread-р ажиллана)

void CTaskingDoc::InitSpinners() { int i; POSITION pos = GetFirstViewPosition(); if (pos != NULL) { CView* pView = GetNextView(pos); for (i = 0; i < 4; i++) { m_cSpin[i].SetViewWnd(pView);

Page 50: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 50 

m_cSpin[i].SetContinue(NULL); switch (i) { case 1: m_cSpin[i].SetContinue(&((CTaskingView*)pView)->m_bThread1); break; case 3: m_cSpin[i].SetContinue(&((CTaskingView*)pView)->m_bThread2); break; } CalcPoint(i, &m_cSpin[i]); } } }

19. Харин энэ үүсгэсэн функц дэх үйлдлээ ашиглахын тулд шинээр баримт үүсгэх бүрд дуудах шаардлагатай. Иймээс document классын OnNewDocument функцэд InitSpinners функцыг дуудах кодыг нэмэх хэрэгтэй.

20. Spinner-н үйлдлийг хялбарчилахын тулд өгөгдсөн дугаартай эргэлдэгч шулууныг дараагийн байрлалд зурах функц нэмж ашиглая.

void CTaskingDoc::DoSpin(int nIndex) { m_cSpin[nIndex].Draw(); }

Программын урсгалын Thread ашиглах 21. Программ болгон өөр өөрийн thread-тэй бөгөөд эдгээрийн нэг нь

программ ямар нэгэн үйлдэл хийгээгүй үеийн thread юм. Энэ thread-н дуудагдах функц нь application болгоны стандарт функц байдаг. Прожектийн app классын гишүүн OnIdle функц юм. Иймээс уг функцэд шулууныг эргэлдүүлэх үйлдлийг хийж өгнө. Өөрөөр хэлбэл checkbox-уудын төлвөөс хамаарч эргэлдэгч шулууны үйлдлийг хийнэ. Checkbox –уудын төлөв өөрчлөгдөхөд эргэлдэгч шулуунуудын байдал мөн өөрчлөгдөнө. Энэ үйлдлийг хавсаргасан хувьсагчаар нь дамжуулж хийх учир Idle-н checkbox-уудад нэгэн адил үйлдэл хийнэ. Иймээс доорхи функцийг нэмж checkbox-уудын төлөв өөрчлөгдөх агшинтай холбо. (BN_CLICKED)

void CTaskingView::OnCbonidle() { // TODO: Add your control notification handler code here UpdateData(true); }

22. Ингээд OnIdle функцэд хийгдэх үйлдэл нь BOOL CTaskingApp::OnIdle(LONG lCount) { POSITION pos = GetFirstDocTemplatePosition(); if (pos) { CDocTemplate* pDocTemp = GetNextDocTemplate(pos); if (pDocTemp) { POSITION dPos = pDocTemp->GetFirstDocPosition(); if (dPos) { CTaskingDoc* pDocWnd = (CTaskingDoc*)pDocTemp->GetNextDoc(dPos); if (pDocWnd) { POSITION vPos = pDocWnd->GetFirstViewPosition(); if (vPos) { CTaskingView* pView =(CTaskingView*)pDocWnd->GetNextView(vPos); if (pView) { if (pView->m_bOnIdle1) pDocWnd->DoSpin(0); if (pView->m_bOnIdle2) pDocWnd->DoSpin(2); } } } } } } return CWinApp::OnIdle(lCount); }

Page 51: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 51 

23. Программаа хөрвүүлж ажиллагаагааг нь шалгавал зөвхөн хулганы заагчийн шилжүүлэхэд шулуун эргэлдэж байна. Үүнийг хулганы заагчаас хамаарахгүй эргэлддэг болгохын тулд OnIdle функцэд дараах өөрчлөлтийг хийж өг.

BOOL CTaskingApp::OnIdle(LONG lCount) { CWinApp::OnIdle(lCount); POSITION pos = GetFirstDocTemplatePosition(); if (pos) { . . . } return TRUE; }

24. Программаа хөрвүүлж ажиллагааг нь шалгавал эргэлдэгч шулуун нь хулганаас хамаара сож байна. хгүй болсон боловч цэс рүү ороход зог

Хэрэглэгчийн thread оруулах 25. Хэрэглэгчийн thread-н хувьсагч нь CWinThread төрлийн хувьсагч байна.

Энэ хувьсагч нь тухайн thread-г зогсоох, эхлүүлэх үйлдлүүдийг удирдах үүрэгтэй. Бидний программд хэрэглэгчийн thread-р 2 шулуун эргэлдүүлэх учир документ класст 2 хувьсагч зарлах хэрэгтэй. Үүнийг массив хэлбэрээр зарлая. (CWinThread* m_pSpinThread[2] (private))

26. Хэрэглэгчийн thread-д хийгдэх үйлдлийг тусад нь функц байдлаар бичиж өгдөг. Өөрөөр хэлбэл ямарч классын гишүүн функц биш global байдлаар бичиж өгнө. Уг функц нь UINT төрөлтэй ба PVOID төрлийн параметртэй байна. Параметрт дамжигдаж ирэх хувьсагчийг AfxBeginThread функцэд тодорхойлж өгдөг. Бидний программын хувьд дээрхи функц нь дараах байдалтай байна.

#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 UINT ThrdFunc(LPVOID pParam) { CSpinner* lpSpin = (CSpinner*)pParam; BOOL* pbContinue = lpSpin->GetContinue(); while (*pbContinue) lpSpin->Draw(); return 0; } class CTaskingDoc : public CDocument { protected: // create from serialization only CTaskingDoc();

27. 2 thread-ээ удирдах ажиллагааг нь эхлүүлэх, зогсоох үйлдлийг нэг функцээр хийж болно. Уг функцэд аль thread нь эхлэх, болон дуусах йүлдлийг хийхээс гадна ажиллаж байгаа thread-г зогсоох, зогсож байгааг эхлүүлэх үйлдэл хийгдэнэ.

28. Документ класст доорхи функцийг нэм. void CTaskingDoc::SuspendSpinner(int nIndex, BOOL bSuspend) { // if suspending the thread if (!bSuspend) { // Is the pointer for the thread valid? if (m_pSpinThread[nIndex]) { // Get the handle for the thread HANDLE hThread = m_pSpinThread[nIndex]->m_hThread; // Wait for the thread to die ::WaitForSingleObject (hThread, INFINITE); } } else // We are running the thread { int iSpnr; // Which spinner to use? switch (nIndex) { case 0: iSpnr = 1; break; case 1:

Page 52: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 52 

iSpnr = 3; break; } m_pSpinThread[nIndex] = AfxBeginThread(ThrdFunc, (LPVOID)&m_cSpin[iSpnr], THREAD_PRIORITY_NORMAL,0,0,NULL); } }

Дээрхи функцэд ашиглагдаж байгаа WaitForSingleObject функц нь thread-г зогсоох үүрэгтэй. Харин AfxBeginThread нь thread-г эхлүүлж байна. 29. Одоо thread-үүдийг View класстай холбох өөрөөр хэлбэл checkbox-

уудтай холбох үйлдэл үйлдлээ. IDC_CBTHREAD checkbox-ууд дээр товч дарагдахад хийгдэх үйлдлийг дараах байдалтайгаар тодорхойлж өг.

void CTaskingView::OnCbthread1() { // TODO: Add your control notification handler code here UpdateData(TRUE); CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); ASSERT_VALID(pDocWnd); pDocWnd->SuspendSpinner(0, m_bThread1); } void CTaskingView::OnCbthread2() { // TODO: Add your control notification handler code here UpdateData(TRUE); CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); ASSERT_VALID(pDocWnd); pDocWnd->SuspendSpinner(1, m_bThread2); }

30. Программаа хөрвүүлж ажиллагааг нь шалгахад хэрэглэгчийн thread-р эргэлдэж байгаа шулуун нь цэснээс хамаарахгүй байгаа нь харагдаж байна.

31. Эцэст нь программаас гарахад бүх ажиллаж байгаа thread-үүдийг зогсоож устгах шаардлагатай.

void CTaskingView::OnDestroy() {

CFormView::OnDestroy(); // TODO: Add your message handler code // Is the first thread running? if (m_bThread1) {

// Specify to stop the first thread m_bThread1 = FALSE; // Get a pointer to the document CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); // Did we get a valid pointer? ASSERT_VALID(pDocWnd); // Suspend the spinner thread pDocWnd->SuspendSpinner(0, m_bThread1);

} // Is the second thread running? if (m_bThread2) {

// Specify to stop the second thread m_bThread2 = FALSE; // Get a pointer to the document CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); // Did we get a valid pointer? ASSERT_VALID(pDocWnd); // Suspend the spinner thread pDocWnd->SuspendSpinner(1, m_bThread2);

} }

        

Page 53: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 53 

Lecture №13-14 Сэдэв: MultiThread, Multitasking Application

Өнөөдөр бид multithread application-ы энгийн жишээ болгон SDI хэлбэрийн программ дээр тус тусын thread-р ажиллах эргэлдэх өнгийн шулуунуудыг хэрхэн зохион байгуулахын авч үзнэ. Thread-н энгийн хэлбэр болох программын өөрийн урсгалыг ашиглах, нэг функц ашиглах хоёрыг ашиглан 4 эргэлдэгч шулуун үүсгэнэ. Үүний тулд программд 4 checkbox байх бөгөөд 2 нь программын урсгалаар эргэлдэх 2 шулууныг, нөгөө 2 нь хэрэглэгчийн үүсгэснээр эргэлдэх 2 шулууныг тус тус удирдана.

Программын урсгалыг үүсгэх 32. SDI applicationүүсгэ. Программын нэрийг Tasking гэж өг. 33. View класс нь CFormView-с удамшин гарах ёстой. 34. Доорхи контролуудыг программын цонхонд байрлуул Object Property Setting Check Box ID IDC_CBONIDLE1 Caption On &Idle Thread 1Check Box ID IDC_CBTHREAD1 Caption Thread &1 Check Box ID IDC_CBONIDLE2 Caption On Idle &Thread 2Check Box ID IDC_CBTHREAD2 Caption Thread &2 35. Программын цонхны харагдах байдал

36. Программын контролуудад доорхи хувьсагчдыг хавсарга. Object Name Category Type IDC_CBONIDLE1 m_bOnIdle1 Value BOOL IDC_CBONIDLE2 m_bOnIdle2 Value BOOL IDC_CBTHREAD1 m_bThread1 Value BOOL IDC_CBTHREAD2 m_bThread2 Value BOOL 37. Эргэлдэгч шулуунуудыг үүсгэхийн тулд ерөнхийд нь нэг класс авч

ашиглая. Энэ классаа thread болгон дээрээ дуудаж шулуунаа эргэлдүүлэх болно. Өөрөөр хэлбэл эргэлдэгч 4 шулуун нь нэг классын хувьсагчид байна. Шинээр үүсгэх класс нь дараагийн шулуун нь хаана зурагдахыг өөрөө тооцоолон программын цонхон дээр зурах бөгөөд мөн өнгөө өөрчилнө. Үүний тулд программын цонхны DC заагч хэрэгтэй.

38. CSpinner нэртэй CObject классаас удамшин гарсан класс шинээр нэм. 39. Шинээр үүсгэсэн класстаа дараах хувьсагчдыг нэмэх шаардлагатай.

39.1. Одоогийн өнгө (int m_crColor) 39.2. Эргэлдэгч шулууны байрлал (int m_iMinute) 39.3. Эргэлтийн радиус (int m_iRadius) 39.4. Эргэлтийн төвийн цэг (CPoint m_pCenter)

Page 54: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 54 

39.5. Шулууны өнгийн хүснэгт (static COLORREF m_crColors[8]) 39.6. View обьектын заагч (CWnd* m_pViewWnd) 39.7. Шулуун эргэлдэж буй эсэх (BOOL* m_bContinue)

40. Хувьсагчдаа нэмсэн бол классын үүсгэгч функцэд доорхи үйлдлийг хийнэ CSpinner::CSpinner() { m_iRadius = 0; m_nMinute = 0; m_crColor = 0; m_pViewWnd = NULL; m_bContinue = NULL; }

41. Мөн класстаа дараах хэдэн inline функцүүдийг нэмбэл классын зарлалт дараах байдалтай болно.

class CSpinner : public CObject { public: BOOL* GetContinue() {return m_bContinue;} void SetContinue(BOOL* bContinue) { m_bContinue = bContinue;} CWnd* GetViewWnd() { return m_pViewWnd;} void SetViewWnd(CWnd* pWnd) { m_pViewWnd = pWnd;} void SetLength(int iLength) { m_iRadius = iLength;} void SetPoint(CPoint pPoint) { m_pCenter = pPoint;} CSpinner(); virtual ~CSpinner(); private: BOOL* m_bContinue; CWnd* m_pViewWnd; static COLORREF m_crColors[8]; int m_iRadius; CPoint m_pCenter; int m_nMinute; int m_crColor; };

42. Шаардлагатай хувьсагчдын анхны утгыг олгох, утгыг өөрчлөх зэрэг функцүүдийг нэмсэн бол шулууны өнгийг тодорхойлох хүснэгтийн утгыг олгох хэрэгтэй.

static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif COLORREF CSpinner::m_crColors[8] = { RGB( 0, 0, 0), // Black RGB( 0, 0, 255), // Blue RGB( 0, 255, 0), // Green RGB( 0, 255, 255), // Cyan RGB( 255, 0, 0), // Red RGB( 255, 0, 255), // Magenta RGB( 255, 255, 0), // Yellow RGB( 255, 255, 255) // White }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CSpinner::CSpinner() { m_iRadius = 0; m_nMinute = 0;

43. Одоо шулууныг эргэлдүүлэх функцыг зохион байгуулах хэрэгтэй. Өөрөөр хэлбэл дуудагдах болгондоо шулууныг дараагийн байрлалд нь зурах функцыг зохион байгуулна. (void Draw();)

44. Уг функц нь шулууныг төвийн цэгээс захын цэг рүү, одоогийн өнгөтэй Pen-г үүсгэн зурах бөгөөд шулуун зурагдсан бол хуучин Pen-г сэргээгээд гарахаасаа өмнө дараагийн шулууны байрлалыг тооцоолоод гарна. Мөн өнгийг солих үйлдлийг хийнэ. Ингээд функц нь дараах байдалтай байна.

void CSpinner::Draw() { CDC *pDC = m_pViewWnd->GetDC(); pDC->SetMapMode (MM_LOENGLISH); CPoint org = m_pCenter; CPoint pStartPoint; pStartPoint.x = (m_iRadius / 2); pStartPoint.y = (m_iRadius / 2);

Page 55: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 55 

org.x = m_pCenter.x + (m_iRadius / 2); org.y = m_pCenter.y + m_iRadius; pDC->SetViewportOrg(org.x, org.y); CPoint pEndPoint; double nRadians = (double) (m_nMinute * 6) * 0.017453292; pEndPoint.x = (int) (m_iRadius * sin(nRadians)); pEndPoint.y = (int) (m_iRadius * cos(nRadians)); CPen pen(PS_SOLID, 0, m_crColors[m_crColor]); CPen* pOldPen = pDC->SelectObject(&pen); pDC->MoveTo (pEndPoint); pDC->LineTo (pStartPoint); pDC->SelectObject(&pOldPen); m_pViewWnd->ReleaseDC(pDC); if (++m_nMinute == 60) { m_nMinute = 0; if (++m_crColor == 8) m_crColor = 0; } }

45. Дээрхи үйлдлийг хи рхойлох шаардлагатай. йхэд math.h толгой файлыг тодоSpinner-үүдийг ашиглах

46. Spinner классыг үүсгэсний дараа үүнийг программд ашиглах, программын цонхон дээр эргэлдүүлдэх кодыг хийж өгөх шаардлагатай. Document класст private хандалттай m_cSpin[4] нэртэй CSpinner төрлийн хувьсагч нэм.

47. TaskingDoc.cpp файлд Spinner.h файлын зарлалтыг нэм. 48. Хамгийн эхний авах шаардлагатай арга хэмжээ бол эргэлдэгч шулуунуудын

эхний байрлалыг тооцоолох явдал юм. Өөрөөр хэлбэл тухайн Spinner-н массивын индексээр байрлах байрлалыг нь олох тооцоолох хэрэг юм. CtaskingDoc класст доорхи функцыг нэм.

void CTaskingDoc::CalcPoint(int nID, CSpinner *pSpin) { RECT lWndRect; CPoint pPos; int iLength; CTaskingView *pWnd; pWnd = (CTaskingView*)pSpin->GetViewWnd(); pWnd->GetClientRect(&lWndRect); iLength = lWndRect.right / 6; switch (nID) { case 0: // Position the first spinner pPos.x = (lWndRect.right / 4) - iLength; pPos.y = (lWndRect.bottom / 4) - iLength; break; case 1: // Position the second spinner pPos.x = ((lWndRect.right / 4) * 3) - iLength; pPos.y = (lWndRect.bottom / 4) - iLength; break; case 2: // Position the third spinner pPos.x = (lWndRect.right / 4) - iLength; pPos.y = ((lWndRect.bottom / 4) * 3) - (iLength * 1.25); break; case 3: // Position the fourth spinner pPos.x = ((lWndRect.right / 4) * 3) - iLength; pPos.y = ((lWndRect.bottom / 4) * 3) - (iLength * 1.25); break; } pSpin->SetLength(iLength); pSpin->SetPoint(pPos); }

49. Ингээд эргэлдэгч шулуунуудыг программд ашиглахад тэдгээрийн анхны утгуудыг зөв олгох мөн checkbox-ууд дахь тэмдэглэгээ өөрчлөгдөхөд төлөв байдлыг зохицуулах шаардлагатай. Үүний тулд доорхи функцыг нэмж ашиглая. (0,2-р spinner-үүд нь программын урсгалаар, 1,3-рх нь хэрэглэгчийн үүсгэсэн thread-р ажиллана)

void CTaskingDoc::InitSpinners() { int i; POSITION pos = GetFirstViewPosition(); if (pos != NULL) { CView* pView = GetNextView(pos); for (i = 0; i < 4; i++) { m_cSpin[i].SetViewWnd(pView);

Page 56: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 56 

m_cSpin[i].SetContinue(NULL); switch (i) { case 1: m_cSpin[i].SetContinue(&((CTaskingView*)pView)->m_bThread1); break; case 3: m_cSpin[i].SetContinue(&((CTaskingView*)pView)->m_bThread2); break; } CalcPoint(i, &m_cSpin[i]); } } }

50. Харин энэ үүсгэсэн функц дэх үйлдлээ ашиглахын тулд шинээр баримт үүсгэх бүрд дуудах шаардлагатай. Иймээс document классын OnNewDocument функцэд InitSpinners функцыг дуудах кодыг нэмэх хэрэгтэй.

51. Spinner-н үйлдлийг хялбарчилахын тулд өгөгдсөн дугаартай эргэлдэгч шулууныг дараагийн байрлалд зурах функц нэмж ашиглая.

void CTaskingDoc::DoSpin(int nIndex) { m_cSpin[nIndex].Draw(); }

Программын урсгалын Thread ашиглах 52. Программ болгон өөр өөрийн thread-тэй бөгөөд эдгээрийн нэг нь

программ ямар нэгэн үйлдэл хийгээгүй үеийн thread юм. Энэ thread-н дуудагдах функц нь application болгоны стандарт функц байдаг. Прожектийн app классын гишүүн OnIdle функц юм. Иймээс уг функцэд шулууныг эргэлдүүлэх үйлдлийг хийж өгнө. Өөрөөр хэлбэл checkbox-уудын төлвөөс хамаарч эргэлдэгч шулууны үйлдлийг хийнэ. Checkbox –уудын төлөв өөрчлөгдөхөд эргэлдэгч шулуунуудын байдал мөн өөрчлөгдөнө. Энэ үйлдлийг хавсаргасан хувьсагчаар нь дамжуулж хийх учир Idle-н checkbox-уудад нэгэн адил үйлдэл хийнэ. Иймээс доорхи функцийг нэмж checkbox-уудын төлөв өөрчлөгдөх агшинтай холбо. (BN_CLICKED)

void CTaskingView::OnCbonidle() { // TODO: Add your control notification handler code here UpdateData(true); }

53. Ингээд OnIdle функцэд хийгдэх үйлдэл нь BOOL CTaskingApp::OnIdle(LONG lCount) { POSITION pos = GetFirstDocTemplatePosition(); if (pos) { CDocTemplate* pDocTemp = GetNextDocTemplate(pos); if (pDocTemp) { POSITION dPos = pDocTemp->GetFirstDocPosition(); if (dPos) { CTaskingDoc* pDocWnd = (CTaskingDoc*)pDocTemp->GetNextDoc(dPos); if (pDocWnd) { POSITION vPos = pDocWnd->GetFirstViewPosition(); if (vPos) { CTaskingView* pView =(CTaskingView*)pDocWnd->GetNextView(vPos); if (pView) { if (pView->m_bOnIdle1) pDocWnd->DoSpin(0); if (pView->m_bOnIdle2) pDocWnd->DoSpin(2); } } } } } } return CWinApp::OnIdle(lCount); }

Page 57: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 57 

54. Программаа хөрвүүлж ажиллагаагааг нь шалгавал зөвхөн хулганы заагчийн шилжүүлэхэд шулуун эргэлдэж байна. Үүнийг хулганы заагчаас хамаарахгүй эргэлддэг болгохын тулд OnIdle функцэд дараах өөрчлөлтийг хийж өг.

BOOL CTaskingApp::OnIdle(LONG lCount) { CWinApp::OnIdle(lCount); POSITION pos = GetFirstDocTemplatePosition(); if (pos) { . . . } return TRUE; }

55. Программаа хөрвүүлж ажиллагааг нь шалгавал эргэлдэгч шулуун нь хулганаас хамаара сож байна. хгүй болсон боловч цэс рүү ороход зог

Хэрэглэгчийн thread оруулах 56. Хэрэглэгчийн thread-н хувьсагч нь CWinThread төрлийн хувьсагч байна.

Энэ хувьсагч нь тухайн thread-г зогсоох, эхлүүлэх үйлдлүүдийг удирдах үүрэгтэй. Бидний программд хэрэглэгчийн thread-р 2 шулуун эргэлдүүлэх учир документ класст 2 хувьсагч зарлах хэрэгтэй. Үүнийг массив хэлбэрээр зарлая. (CWinThread* m_pSpinThread[2] (private))

57. Хэрэглэгчийн thread-д хийгдэх үйлдлийг тусад нь функц байдлаар бичиж өгдөг. Өөрөөр хэлбэл ямарч классын гишүүн функц биш global байдлаар бичиж өгнө. Уг функц нь UINT төрөлтэй ба PVOID төрлийн параметртэй байна. Параметрт дамжигдаж ирэх хувьсагчийг AfxBeginThread функцэд тодорхойлж өгдөг. Бидний программын хувьд дээрхи функц нь дараах байдалтай байна.

#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 UINT ThrdFunc(LPVOID pParam) { CSpinner* lpSpin = (CSpinner*)pParam; BOOL* pbContinue = lpSpin->GetContinue(); while (*pbContinue) lpSpin->Draw(); return 0; } class CTaskingDoc : public CDocument { protected: // create from serialization only CTaskingDoc();

58. 2 thread-ээ удирдах ажиллагааг нь эхлүүлэх, зогсоох үйлдлийг нэг функцээр хийж болно. Уг функцэд аль thread нь эхлэх, болон дуусах йүлдлийг хийхээс гадна ажиллаж байгаа thread-г зогсоох, зогсож байгааг эхлүүлэх үйлдэл хийгдэнэ.

59. Документ класст доорхи функцийг нэм. void CTaskingDoc::SuspendSpinner(int nIndex, BOOL bSuspend) { // if suspending the thread if (!bSuspend) { // Is the pointer for the thread valid? if (m_pSpinThread[nIndex]) { // Get the handle for the thread HANDLE hThread = m_pSpinThread[nIndex]->m_hThread; // Wait for the thread to die ::WaitForSingleObject (hThread, INFINITE); } } else // We are running the thread { int iSpnr; // Which spinner to use? switch (nIndex) { case 0: iSpnr = 1; break; case 1:

Page 58: Vizual programchilal cu lekts

Визуал програмчлал СИ++ хичээлийн лекцийн хураангуй

Боловсруулсан багш: Т.Уламбаяр  Page 58 

iSpnr = 3; break; } m_pSpinThread[nIndex] = AfxBeginThread(ThrdFunc, (LPVOID)&m_cSpin[iSpnr], THREAD_PRIORITY_NORMAL,0,0,NULL); } }

Дээрхи функцэд ашиглагдаж байгаа WaitForSingleObject функц нь thread-г зогсоох үүрэгтэй. Харин AfxBeginThread нь thread-г эхлүүлж байна. 60. Одоо thread-үүдийг View класстай холбох өөрөөр хэлбэл checkbox-

уудтай холбох үйлдэл үйлдлээ. IDC_CBTHREAD checkbox-ууд дээр товч дарагдахад хийгдэх үйлдлийг дараах байдалтайгаар тодорхойлж өг.

void CTaskingView::OnCbthread1() { // TODO: Add your control notification handler code here UpdateData(TRUE); CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); ASSERT_VALID(pDocWnd); pDocWnd->SuspendSpinner(0, m_bThread1); } void CTaskingView::OnCbthread2() { // TODO: Add your control notification handler code here UpdateData(TRUE); CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); ASSERT_VALID(pDocWnd); pDocWnd->SuspendSpinner(1, m_bThread2); }

61. Программаа хөрвүүлж ажиллагааг нь шалгахад хэрэглэгчийн thread-р эргэлдэж байгаа шулуун нь цэснээс хамаарахгүй байгаа нь харагдаж байна.

62. Эцэст нь программаас гарахад бүх ажиллаж байгаа thread-үүдийг зогсоож устгах шаардлагатай.

void CTaskingView::OnDestroy() {

CFormView::OnDestroy(); // TODO: Add your message handler code // Is the first thread running? if (m_bThread1) {

// Specify to stop the first thread m_bThread1 = FALSE; // Get a pointer to the document CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); // Did we get a valid pointer? ASSERT_VALID(pDocWnd); // Suspend the spinner thread pDocWnd->SuspendSpinner(0, m_bThread1);

} // Is the second thread running? if (m_bThread2) {

// Specify to stop the second thread m_bThread2 = FALSE; // Get a pointer to the document CTaskingDoc* pDocWnd = (CTaskingDoc*)GetDocument(); // Did we get a valid pointer? ASSERT_VALID(pDocWnd); // Suspend the spinner thread pDocWnd->SuspendSpinner(1, m_bThread2);

} }