Windows-ийн үндсэн үйлчилгээ болон api функцууд. Windows api - үйлдлийн системийн функцүүдийн багц. Яагаад WinAPI-г нэг дор хийх вэ?

Аливээ! Аливээ! Өнөөдөр бид эцэст нь Windows цонхыг дахин нээж байна. Баяртай хөөрхий консол!

Тэр болтол та C++ синтаксийг мэддэг, гогцоо, гогцоо хэрхэн ашиглах, функцууд хэрхэн сайн ажилладагийг ойлгох ёстой. Хэрэв та тэнгисийн цэргийн тулалдаанд баригдсан бол барьж авсан зүйлээ тэмдэглэж болно.

Ugorsk бүртгэлийн маягт

WinAPI-д ашигладаг бүх кодыг Украин хэлбэрээр бичдэг. Кодоо сайн бичих нь сайн хэрэг.

Өөрчлөлтийн нэрийн өмнө хэний үсгийг байрлуулах ёстой. Чухал үүргүүдийн нэрсийн бүх үгс агуу үсгээр эхэлдэг.

Угтваруудын тэнхлэг:

b – bool төрлийг өөрчлөх.
l - төрөл урт бүхэл тоог өөрчлөх.
w – үг (үг) – 16 бит. Гарын үсэггүй богино төрлийн нэр.
dw – давхар үг (давхар үг) – 32 бит. Zminna төрөл unsigned long.
sz - мөр төгсгөлтэй тэг. Бид байнга vikorized зүгээр л энгийн эгнээ.
p эсвэл lp - заагч. lp (урт заагч) - эдгээр үзүүлэлтүүдийг өнгөрсөн үеэс шилжүүлсэн. Хамтдаа lp i p нь ижил утгатай.
h – тайлбар (төрлийн бариул).

Жишээлбэл, тэнхлэгийг дараах байдлаар нэрлэдэг.

хүчингүй * pData;

Энэхүү мэдүүлгийн маягтыг Microsoft компани зохиогчийн эрхээр хамгаална. Өөрчлөгчийг нэрлэх энэ аргыг шүүмжлэх хүмүүс цөөнгүй байдаг. Гэхдээ ижил төстэй яриа (ялангуяа кодчилолын тухай) нь агуу компаниудад амин чухал юм.

Тогтмол танигч нь WM_DESTROY гэсэн агуу үсгүүд дээр суурилдаг гэдгийг сануулъя. WM_DESTOY - утга 2, тогтмол нь define-ээр тодорхойлогдоно.

Нэмж дурдахад winAPI нь дахин хуваарилах олон төрлүүдтэй. Энэ хуудасны тэнхлэг нь http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx бөгөөд та бүх төрлийн Windows-ийн тайлбарыг (англи хэл дээр) олж болно.

Мөн бидний ойлгоогүй өөр нэг яриа. Шүршүүрт ихэвчлэн NULL утгыг өгдөг. Энэ нь ердөө л 0 бөгөөд NULL (тэг) утгыг өгсөн гарын үсэг зурсан хүмүүс санах ойг хуваалцахгүй гэдгийг анхаарна уу.

Windows API (WinAPI)

Бүх Windows програмууд нь WinAPI програмчлалын тусгай интерфейсийг ашигладаг. Movi C дахь функц, бүтцийн багц нь таны програмыг Windows дээр сайн ажиллах боломжийг олгодог.

Windows API нь үйлдлийн системтэй ажиллах гайхалтай чадвартай. Та хэлж болно - хил хязгааргүй.

Бид WinAPI-ийн 100 чадварыг л харж чадахгүй. Яг одоо би илүү их материал авахыг хүсч байна, гэхдээ энэ нь маш их цаг хугацаа шаардагдах бөгөөд WinAPI-г намагт татаж авсны дараа бид DirectX-т хүрэх болно.WinAPI-ийн тайлбар, бид хоёр хичээл авах болно (үүнийг оруулаад) Тэд зөвхөн програмын хүрээг харна.Windows.

Windows-д зориулсан програм нь DOS-д зориулсан програм шиг үндсэн үүрэгтэй. Энд энэ функцийг WinMain гэж нэрлэдэг.

WinMain функц

Windows програм нь дараах хэсгүүдээс бүрдэнэ (бүх зүйл WinMain дээр хадгалагддаг):

Ангийн цонхыг үүсгэх, бүртгэх. C++ ангиудтай андуурч болохгүй. WinAPI нь C хэл дээр бичигдсэн бөгөөд бидний мэддэг нийтлэг үгэнд маш олон анги байдаг.
Програмын цонхыг бий болгох.
Мэдлэг бүрэлдэх гол мөчлөг.
Боловсруулалтыг эцсийн журмаар мэдээлнэ. Цонхны процедур нь үндсэн функц юм.
Тэнхлэг ба хэд хэдэн цэг нь Windows програмын үндэс юм. Энэ шинэ хичээлийг сунгаснаар бид бүх зүйлийг нарийвчлан цэгцлэх болно. Хэрэв та програмын тайлбарт төөрсөн бол эдгээр цэгүүд рүү буцна уу.

Одоо бүгдийг нь цэгцэлье:

WinAPI: WNDCLASS бүтэц

Бид эхлээд WNDCLASS-ийн бүтцийн өөрчлөлтийг үүсгэж хадгалах хэрэгтэй бөгөөд үүний үндсэн дээр эцсийн ангийг бүртгэх хэрэгтэй.

Тэнхлэг нь ийм бүтэцтэй харагдаж байна:

миний c++ код typedef struct ( UINT загвар; // цонхны загвар WNDPROC lpfnWndProc; // цонхны процедурын үзүүлэлт int cbClsExtra; // ангийн дараа нэмэлт байт. Эхлээд 0 int cbWndExtra; // цонхны жишээний дараа нэмэлт байт. Эхлээд тохируулна. 0 / instance lar програм: WinMain HICON hIcon-д параметр хэлбэрээр дамжуулагдсан; // програмын дүрс HCURSOR hCursor; // програмын курсор HBRUSH hbrBackground; // дэвсгэр өнгө LPCTSTR lpszMenuName; ;

WinAPI агуулах дахь WNDCLASS бүтэц нь үүсгэсэн цонхны үндсэн хүчийг тодорхойлдог: дүрсүүд, хулганы курсор харах, цонхны цэс, цонхонд ямар нэмэлтүүд байх болно...

Энэ бүтцийг хадгалсны дараа та энэ үндсэн дээр эцсийн ангид бүртгүүлж болно. C++ хэлтэй ижил ангиуд байдаггүй. Энэ бол таны системд бүртгүүлсэн загвар гэдгийг та одоо санаж байгаа бөгөөд одоо энэ загвар дээр үндэслэн шинэ загвар үүсгэж болно. Мөн энэ бүх өдрүүдийг эрх баригчид удирдах болно гэдгийг WNDCLASS-ийн бүтцийн өөрчлөлтөөс мэдэж авсан.

WinAPI: CreateWindow функц

Шинэ ангиа бүртгүүлсний дараа үндсэн программууд бий болно (бид өөр цэг рүү шилжсэн). CreateWindow нэмэлт функцийг туршиж үзээрэй. Доромжилсон прототип байж болно:

миний c++ код HWND CreateWindow(LPCTSTR lpClassName // ангийн нэр LPCTSTR lpWindowName // цонхны нэр (гарчигт харагдана) DWORD dwStyle // цонхны загвар int x // дэлгэцийн зүүн ирмэгийн хэвтээ координат int y // дээд ирмэгийн босоо координат screen int nWidth, // цонхны өргөн int nHeight, // цонхны өндөр HWND hWndParent, // аавын цонх HMENU hMenu, // цэсийн тайлбар HINSTANCE hInstance, // программын жишээ LPVOID lpParam // параметр; үргэлж NULL гэж тохируулна);

Цонхны ангилалд (WNDCLASS бүтэц) цонхны үндсэн эрхүүд өгөгдсөн тул цонхны тусгай цонхны параметрүүдийг энд харуулав: цонхны хэмжээ, координат...

Энэ функц нь тайлбарын цонхыг эргүүлдэг. Дэлгэрэнгүй тайлбарыг та тодорхойлогчтой төстэй цонх руу очиж болно.

Энд маш олон шинэ төрлүүд байгааг анхаарна уу. Ер нь бүх өмхий үнэр нь хуучирсан, дөнгөж нэрээ өөрчилсөн. Жишээ нь: HWND нь HANDLE төрөлд дахин хуваарилалт биш бөгөөд энэ нь өөрийн замаар PVOID-д дахин хуваарилалт бөгөөд энэ нь мөн хүчингүй болно*. Үнэн үнэхээр гүн булшлагдсан! Эцсийн эцэст, HWND төрөл нь хүчингүй байдлын шинж тэмдэг биш юм.

Цонх нь олон хэсгээс бүрдэнэ. Үнэн хэрэгтээ, програм бүрт та дараах зүйлийг харах болно: цонхны гарчиг, системийн цэс (цонхны зүүн дээд хэсэгт байрлах програмын дүрс дээр дарна уу), цонхтой ажиллах гурван системийн товчлуур: гэрэл асах, бүтэн дэлгэц, хаах. Үүнээс гадна бараг үргэлж цэс байдаг. Үлдсэн нэгнийх нь тэнхлэг бидний дотор байхгүй нь гарцаагүй. Мэдээжийн хэрэг, цонхны ихэнх хэсгийг гэгддэг зүйл эзэлдэг. үйлчлүүлэгчийн ажилладаг үйлчлүүлэгчийн бүс.

Энэ нь цонхны горимоос илүү дээр юм. Хэрэв бид DiectX-тэй удаан хугацаанд дасгал хийвэл бүтэн дэлгэцийн горимыг ашиглахгүй.

Мессеж боловсруулах

Windows дээрх бүх дэвшилтэт програмуудын гол давуу тал нь шинэчлэлтийг боловсруулах явдал юм.

Жишээлбэл, хэрэглэгч гар дээрх товчлуурыг дарахад товчлуур дарагдсан тухай мэдэгдэл үүсдэг. Дараа нь та товчлуурыг дарахад идэвхтэй байсан програм руу очих хэрэгтэй болно.

Энд бид үйл явдалтай байна - товчлуур дарагдсан.

Хулганы курсорыг хөдөлгөж, програмын фокусыг өөрчлөх, гарын товчлуурыг дарах, цонхыг хаах зэрэг үйлдлүүд байж болно. Энэ нь нэлээд баян юм. Дуже! Нэг секундын дотор үйлдлийн системд олон арван мессеж үүсгэж болно.

Тиймээс, хэрэв ямар нэгэн хариу ирвэл үйлдлийн систем нь мэдэгдэл үүсгэдэг: товчлуурыг дарахад хулганы курсорын координатууд өөрчлөгдөж, шинэ цонх нээгдэнэ.

Мэдээллийг үйлдлийн систем болон янз бүрийн программуудын аль алинаар нь үүсгэж болно.

Удахгүй болох захиалгын бүтэц, дүр төрх:

миний c++ код typedef struct tagMSG ( HWND hwnd; // UINT мессежийг харуулсан цонх; // мэдэгдлийн код WPARAM wParam; // LPARAM lParam параметр; // параметр DWORD цаг; // мэдэгдэл гарсан цаг POINT pt; // хулганы курсорыг зохицуулдаг) MSG;

Бүтэцүүдийг typedefs ашиглан дахин хуваарилдаг болохыг анхаарна уу.

Энэ бүтцийг бий болгохын тулд та дараах кодыг хурдан ашиглаж болно.

миний c++ код msg.messgae == 2; // эдгээр нь тэнцүү фрагментуудын хоёр эгнээ юм msg.message == WM_DESTROY; // тогтмол WM_DESTROY хуучин хоёр

Энд талбар юм, яку нь, дин код (izi divodelene, Константин WM_Destroy нь урагдаж байна. WM - vid Windows мессеж (Дэд Windows). WM_Destroy - Tser Poldodlennya, Jack General Strivet үед (устгах - устгах).

Кодууд нь нэмэлт тогтмолууд болон WM_ угтварын ард бичигдсэн байдаг: WM_CLOSE, WM_CREATE болон бусад.

MSG бүтэц нь HWND төрөлтэй - Цонхны бариул (цонхны бариул ба цонхны тайлбар). Энэ бол ертөнцийг дүрсэлсэн зүйл юм. Үнэ нь таних тэмдэгт (цонхны нэр) зориулагдсан болно.

Энэ үгийг санаарай - бариул (дүрслэх, дүрслэх). Windows дээр энэ нь маш түгээмэл сэдэв юм. Мөн H үсгээр эхэлсэн бүх төрлийн Windows нь тайлбар юм: дүрсний тайлбар, үсгийн тайлбар, програмын жишээний тайлбар. Миний санаж байгаагаар гуч орчим байдаг.

Windows дээрх програмуудын хоорондын бүх харилцан үйлчлэл нь эдгээр цонхны тайлбарыг (HWND) ашиглан гүйцэтгэдэг.

Өөр нэг чухал тодорхойлогч байдаг - програмын тодорхойлогч (HINSTANCE - WinMain-ийн эхний параметр) - энэ нь өвөрмөц програмын тодорхойлогч юм, учир нь ямар ч үйлдлийн систем хоёр өөр програмыг хольж чадахгүй. Энэ нь ойролцоогоор бар кодтой адил юм. Бид үүнийг дараа нь авч үзэх болно.

Одоо таныг ямар нэгэн үйлдэл хийх үед мэдэгдэл үүсгэж, санах болно: нээх боломжтой тайлбарын цонхыг тохируулж, мэдэгдлийн ID-г тохируулж, параметрүүдийг хадгалсан, цаг (одоогийн) хадгалагдаж, заасан тохиргоог өөрчилж болно. хулганы курсорын координат (та бүтцийг харж болно).

Энэ мэдэгдлийн дараа үйлдлийн системийн дараагийн мэдэгдэл рүү очно уу. Бидний мэдээлэл ирэхэд шаардлагатай цонх руу илгээгдэх болно (Windows нь мэргэжилтнүүдэд арьсны мэдээллийг хэрхэн илгээхийг мэддэг). Хэрэв та хөтөлбөрүүдийн талаар мэддэг бол хөтөлбөрүүдийн талаар мэдээлэл өгөх шаардлагатай болно. Доод тал руугаа ороход хэцүү, уйтгартай болж байна.

Хэрэглэгч ямар нэгэн үйлдэл хийх үед (мэдээлэл гарч ирэн, мессеж үүсгэгдсэн) яг энэ мөчид програм нь энэ үйлдэлд хариу үйлдэл үзүүлэхэд (хөтөлбөр нь мессеж үүсгэсэн) маш их зүйл байгаа нь гайхалтай. мэдээллийн. Та Windows ашигладаг байсан ч программуудаас маш их мэдээлэл авах боломжтой. Эхнийх нь хэдэн зуу, нөгөө нь дор хаяж цөөхөн байж болно.

Цонхны процедур - WndProc

Мэдээллийг зарцуулсан цагаас эхлээд хөтөлбөр дуустал бид үргэлжлүүлнэ. Удаан хугацааны дараа л сүйрч эхэлж байна. Боловсруулахын тулд арьсны програм нь тусгай функцтэй байдаг гэдгийг анхаарна уу - цонхны процедур. Үүнийг WndProc гэж нэрлэдэг (Цонхны процедураас). Өргөтгөх процедурын цонх нь үндсэн програмын гогцоонд хийгдэх бөгөөд мөчлөгийн давталт бүрт дуусгавар болно.

Мэдээллийг (бүтцийн өөрчлөлтийн ОТХ хэлбэрээр) энэ функцэд параметрийн хэлбэрээр ашигладаг: цонхны тайлбар, мэдэгдлийн танигч, хоёр параметр. Цаг болон pt талбарууд цонхны горимд шилждэггүй гэдгийг анхаарна уу. Тотто, энэ нь аль хэдийн "rozіbran" болсныг хэлье.

Цонхны процедурын дундуур шилжүүлэгчийг устгасан бөгөөд энэ нь мэдэгдлийн ID-г шалгах явдал юм. Тэнхлэг нь энгийн цонхны процедурын жишээ юм (энэ нь бүрэн ажиллаж байна):

миний c++ код// HRESULT болон __stdcall дээр цагаа бүү үр. Бид тэднийг дараа нь харах болно. ) // хөрвүүлэгч мэдэгдэхээр шийднэ)

Би хэвээр байна - гол мөчлөг. Вин бүр ч энгийн. Циклийн давталт бүрийг програмаар баталгаажуулдаг. Мэдээлэлтэй болмогц та түүнд татагддаг. Дараа нь циклийг цонхны процедур дээр дарж мэдээллийг боловсруулахыг хүсэх болно.

Тэнхлэг бүрэн дүүрэн байгаа бөгөөд бүх зүйл өнөөдрийнх юм. WinAPI программ нь DOS программтай илүү төстэй болох нь аль хэдийн тодорхой болсон. Би аль хэдийн бичсэнчлэн, ирэх хичээл дээр бид ажиллаж байгаа програмын кодыг харах болно.

Би шинэ төсөл зохиох эрхтэй. Шинэ төслийн цонхноос загвараа сонго - Win32Project (бид өмнө нь Win32 консол програмыг сонгосон). Удахгүй болох цонхнуудын аль нэгэнд Empty Project тугийг бүү тавь, IDE нь бэлтгэсэн програмыг үүсгэх болно.

Хэрэв та project_name.cpp файл дахь кодыг анхааралтай ажиглавал та бидний ярилцсан бүх зүйлийг харах болно: MSG-ийн бүтцийн өөрчлөлт, WNDCLASS бүтцийг дүүргэх, CreateWindow функцээр цонх үүсгэх, програмын үндсэн гогцоо. . Нэмж дурдахад файлд WndProc функц өгөгдсөн. Та WM_COMMAND, WM_PAINT, WM_DESTROY гэсэн свич хайрцагт хэд хэдэн мэдээллийг боловсруулах хэрэгтэй. Файл доторх бүх зүйлийг олоорой.

Бидний харсан зүйлээс гадна програм нь маш олон нэмэлт код агуулдаг. Дараагийн хувилбар дээр бид програмын кодыг харах болно, ингэснээр бүх зүйл баталгаажна. Энэ нь IDE-ийн үүсгэснээс хамаагүй хялбар бөгөөд илүү ухаалаг байх болно.

Хариуцлага

WinAPI яг хажууд нь гарч ирнэ гэж бодож байсан. Олон тооны кросс платформ фреймворкууд байдаг нь удаан хугацааны туршид тодорхой болсон бөгөөд Windows нь зөвхөн ширээний компьютер дээр байдаггүй бөгөөд Microsoft өөрөө дэлгүүртээ энэ мангасыг зөвтгөх нэмэлт програмуудыг нэмэхээс эргэлздэггүй. WinAPI дээр хэрхэн бүтээх талаар энд төдийгүй Интернет даяар олон мянган нийтлэл байдаг бөгөөд сургуулийн өмнөх насны болон түүнээс гадна мянга мянгаар тоологдож байна. Бүхэл бүтэн задралын үйл явц нь атомууд дээр суурилдаггүй, харин субатомын тоосонцор дээр суурилдаг. Юу илүү энгийн, илүү ухаалаг байж болох вэ? Тэгээд би энд байна ...

Гэхдээ бүх зүйл санагдсан шиг энгийн биш юм.

Яагаад одоо WinAPI-ийн талаар?

Нэгэн өдөр нөгөө л сайн зүйлээс болж ядарч явахдаа: Энэ ямар чөтгөр вэ гэж бодов, редакторт нь ямар ч энгийн редакторт байдаг шиг гарын товчлуурыг дарах шиг энгийн хэл байдаггүй.

Би юу яриад байгаа юм бэ? Мөн тэнхлэгийн код:

Кейс WM_KEYDOWN: MessageBox(hwndDlg,"Үх!","Би үхлээ!",MB_YESNO|MB_ICONINFORMATION);
Ийм байдлаар зохиогчид гар дээр нэмэлт дэмжлэг үзүүлэхийг хүсч байсан боловч Windows дахь харилцах цонхны архитектурын бодит байдал нь ийм биеэ даасан байдлыг хатуу шийтгэсэн юм. Эмулятор эсвэл хянагч ашиглаж байсан хэн бүхэн үүнийг мэдэхийг хүсч байна уу?
Юу болов?

Хариулт нь: чи ингэж ажиллах боломжгүй!

Тэгээд WinAPI-ийн коб тэжээл рүү буцаж орвол: Одоогийн байдлаар үүнийг үргэлжлүүлэх маш олон алдартай төслүүд байгаа бөгөөд тийм ч олон биш, учир нь Товчхондоо, та цэвэр API дээр олон илтгэл тавьж чадахгүй (энд та өндөр чанартай хэл, ассемблерийг тэгшитгэхийн тулд эцэс төгсгөлгүй аналоги хийж болно, гэхдээ огт биш). Яагаад үгүй ​​гэж? Зүгээр л використ, тэгээд л болоо.

Асуудлын талаар

Харилцах цонхнууд нь GUI-тэй харьцуулахад ажиллахад хялбар бөгөөд нэгэн зэрэг бидэнд аливаа зүйлийг бие даан хийх боломжийг олгодог. Жишээлбэл, цонхны процедурт байгаа WM_KEYDOWN/WM_KEYUP мэдээллийг DefDlgProc-ийн дэд хэсгүүдээс олж болно, үүнд: Tab навигаци, Esc боловсруулах, Enter товчлуур гэх мэт үгс орно. Нэмж хэлэхэд, та гараар харилцах цонх үүсгэх шаардлагагүй: зүгээр л товчлуурууд, жагсаалтууд, нөөц засварлагчийг нэмж, WinMain CreateDialog/DialogBox дээр товшоод дууслаа.

Ийм бусад нууцыг тойрон гарахад хялбар байдаг. Мөн дор хаяж хоёр бүрэн хууль ёсны арга зам:

  1. RegisterClassEx-ээр дамжуулан өөрийн ангийг үүсгэж, WM_KEYDOWN-г анги боловсруулах процедурт нэмж, харилцах цонх боловсруулах процедур руу дахин чиглүүлээрэй. Тийм болохоор! Та өөрийн ангитай харилцан яриа үүсгэж, харилцан ярианд зориулж ангийн нэрийг тохируулах боломжийг олгодог VS засварлагчийг ашиглаж болно. Энэ талаар мэддэг, өөртөө үйлчилдэг хүн байна уу?
    Илэрхий сул тал: Дахин нэг анги бүртгүүлэх шаардлагатай тул дахин 1 CALLBACK процедур байгаа бөгөөд мөн чанар нь бооцооны нэвтрүүлэгт алга болно. Түүнээс гадна бид мэдэхгүй кудиТэд зөрчигдөж, цагдаа нар сэрэмжтэй байх болно.
  2. Vikoristovat хурдасгагч механизмын хэрэгжилт. Мөн бид харилцах процедурын кодыг хэзээ ч өөрчлөх шаардлагагүй болно! За, яагаад шилжүүлэгч / гэрт нэг эгнээ нэмж болохгүй гэж, гэхдээ үнэ нь доогуур байна.

Хичээл?

Би ингэж хэлэхээс айхгүй байна Сахал WinAPI-ээр дамжуулан цонх үүсгэх заавар нь боловсруулалтын мөчлөгийг хэрхэн мэдээлдэг болохыг харуулсан энгийн кодоор эхэлдэг (би цонхны анги болон бусад холболтыг бэлтгэх дэлгэрэнгүй мэдээллийг орхих болно):

Харин (GetMessage(&msg, nullptr, 0, 0)) ( TranslateMessage(&msg); DispatchMessage(&msg); )
Энд үнэхээр энгийн:

  1. GetMessage() чөтгөрийн захиасыг хашгирч, мөн гол мөч: хоосон учраас урсгалыг хаадаг
  2. WM_KEYDOWN/WM_KEYUP-тай TranslateMessage() нь WM_CHAR/WM_SYSCHAR мэдэгдлийг үүсгэдэг (хэрэв та өөрийн текст засварлагчийг үүсгэхийг хүсвэл энэ нь зайлшгүй шаардлагатай).
  3. DispatchMessage() цонхны процедурт мэдэгдлийг илгээдэг (байгаагаар нь).
Энэ кодыг vikorize хийх нь аюулгүй биш нь тодорхой бөгөөд ийм учраас л ийм байна. Дарсанд хүндэтгэл үзүүлэх:
Тиймээс буцах утга нь тэг, тэг эсвэл -1 байж болно, дараах кодоос зайлсхий:
байхад (GetMessage(lpMsg, hWnd, 0, 0)) ...
Би зөв мөчлөгөөр өгзөгөө доошлуул.

Варто хэлэхдээ Win32-д зориулсан VS загварууд нь ижил үсгийн нэмэлтүүдтэй байдаг буруумөчлөг. Тэгээд үнэхээр галзуу юм. Зохиогчид өөрсдөө эмхэтгэсэн зүйлийг цөөхөн хүн судалж үздэг ч энэ нь априори зөв юм. Мөн буруу код нь алдаануудаар үрждэг бөгөөд үүнийг барьж авахад маш хэцүү байдаг.

Энэхүү кодын фрагментийн дараа, дүрмээр бол хурдасгуурын тухай хэлэлцүүлэг өрнөж, хэд хэдэн шинэ мөр нэмэгддэг (MSDN-ийн хувьд зөв гогцоо бичихийг танд зөвлөж байна):

HACCEL hAccel = Load Accelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; байхад (bRet = GetMessage(&msg, nullptr, 0, 0)) (хэрэв (-1 == bRet) тасарвал; хэрэв (!TranslateAccelerator(msg.hwnd, hAccel, &msg))) ( TranslateMessage(&msg; DispatchMes ; ) ) )
Би энэ сонголтыг ихэвчлэн илүүд үздэг. би вин ( та-дам) Znovu буруу байна!

Би өөрчлөгдсөн хүмүүсийн талаар ярих болно (дараа нь энэ кодтой холбоотой асуудлуудын талаар):

Нөөцийн эхний мөрөнд товчлууруудын хүснэгтийг сонгосон бөгөөд аль нэг формат дээр дарахад WM_COMMAND мэдэгдэл харгалзах тушаалын id-тай гарч ирнэ.

TranslateAccelerator нь үүнийг хийдэг: WM_KEYDOWN болон энэ жагсаалтад байгаа түлхүүр кодыг хэрхэн олж авах, дараа нь (дахин гол цэг) WM_COMMAND (MAKEWPARAM(id, 1)) мессежийг форматлаж, цонхонд нэг өдөр илгээх. эхний аргумент дээр заасан бариул , боловсруулах журам.

Үлдсэн хэллэгээр өмнөх кодтой холбоотой асуудал юу байсан нь тодорхой болсон байх.
Би тайлбарлая: GetMessage нь "цонх" төрлийн БҮХ объектуудад (хүүхдүүд: товчлуурууд, жагсаалтууд гэх мэт) сонгогдсон бөгөөд TranslateAccelerator нь үүсгэсэн WM_COMMAND-г хаашаа илгээх вэ? Энэ нь зөв: товчлуур/жагсаалт руу буцах. Бид WM_COMMAND-г процедурт нэмдэг бөгөөд энэ нь үүнийг арилгах шаардлагатай гэсэн үг юм.

Бидний үүсгэсэн цонхонд TranslateAccelerator ашиглах шаардлагатай болж байна.

HWND hMainWnd = Цонх үүсгэх(...); HACCEL hAccel = Load Accelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; байхад (bRet = GetMessage(&msg, nullptr, 0, 0)) (хэрэв (-1 == bRet) тасарвал; хэрэв (!TranslateAccelerator(hMainWnd, hAccel, &msg))) ( TranslateMessage(&msg); DispatchMess )
Одоо бүх зүйл сайхан, гайхалтай байна: бид бүх зүйлийг нарийвчлан цэгцэлж, бүх зүйл төгс ажиллаж байна.

Би дахин мэднэ. :-) Бидэнд ганцхан зүйл байгаа бол үүнийг зөв хийцгээе. Модал бус шинэ цонх (харилцах цонх) гарч ирмэгц шинэ цонхонд дарах бүх товчлуурууд WM_COMMAND руу хөрвүүлэгдэн хаашаа илгээгддэг вэ? Би үүнийг зөв хэлье: бидний толгой өвддөг.

Энэ үе шатанд би цагдаа нарыг хамгийн дүлий байдлаас нь хааж болохгүй, харин өмнө нь байгаа (эсвэл тайлагдаагүй байж магадгүй) зааварчилгааг үзэхийг зөвлөж байна.

IsDialogMessage

Энэ функцын нэр дээр үндэслэн та энэ нь: аливаа харилцан яриаг мэддэг байх гэсэн утгатай гэж бодож магадгүй юм. Але, юуны түрүүнд чи юу мэдэх вэ? Өөрөөр хэлбэл, энэ мэдээллийн үнэ цэнэ юу вэ?

Энэ нь арай илүү төлөх нь үнэхээр үнэ цэнэтэй юм, энэ нь нэрнээс нь ялгарч байна. Мөн өөртөө:

  • Та Tab/Shift+Tab/Дээш/Доош/Баруун/Зүүн товчлууруудыг ашиглан хүүхдийн удирдлагад шилжих боломжтой. Дээрээс нь өөр зүйл, энэ нь бидэнд хангалттай
  • ESC дээр дарсны дараа WM_COMMAND (IDCANCEL) үүсдэг.
  • Enter товчийг дарсны дараа WM_COMMAND (IDOK) үүснэ, эсвэл мөрөнд товчлуурыг дарсны дараа.
  • Холболтын ард байгаа товчлууруудыг сольдог (ийм товчлууруудын хүрээ нь бусдаас арай илүү гэрэл гэгээтэй байдаг)
  • За, яриа хэлцэл бүхий сурвалжлагч роботын ажлыг хөнгөвчлөх өөр өөр зүйлүүд
Энэ нь бидэнд юу өгөх вэ? Юуны өмнө бид цонхны голд навигацийн талаар бодох шаардлагагүй. Бид бүх зүйлийг маш их хэмнэх ёстой. Ярихаасаа өмнө манай үндсэн цонхонд WS_EX_CONTROLPARENT хэв маягийг нэмснээр табын навигаци хийх боломжтой боловч энэ нь тийм ч ашигтай биш бөгөөд тийм ч ажиллагаатай биш юм..

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

Взагали, та энд роботын аюулгүй байдлын үүднээс Windows-ийн дээд хэсэгт використ хийж байна модаль харилцах цонхнууд, мөн программистуудад модаль бус харилцах цонхнууд дээр дарах боломжийг олгодог. Гэсэн хэдий ч бид үүнийг сайн хэмжүүрээр ашиглаж болно:

Нэмж дурдахад функцийн харилцах функцийг харилцах цонхыг загварчлахад ашигладаг бөгөөд та үүнийг дурын цонхонд ашиглаж болно, ингэснээр караваны тэмдгүүдийг тохируулж, цонхыг тохируулж, гар өөрөө сонгогдсон эсэхийг шалгаарай, ингэснээр та үүнийг сонгох боломжтой. харилцах цонхонд.
Тобто. Одоо давталтыг дараах байдлаар форматлацгаая.

HWND hMainWnd = Цонх үүсгэх(...); HACCEL hAccel = Load Accelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; байхад (bRet = GetMessage(&msg, nullptr, 0, 0)) ( хэрэв (-1 == bRet) завсарлага; хэрэв (!TranslateAccelerator(hMainWnd, hAccel, &msg)) (хэрэв (!IsDialogMessage(hMainWnd) TranslateMessage(&msg)) ; DispatchMessage(&msg); ) ) )
Дараа нь бид бусад Windows харилцах цонхнуудын нэгэн адил навигацыг ашиглах болно. Гэхдээ одоо бид хоёр дутагдалтай талдаа автсан.

  1. Энэ кодыг зөвхөн эелдэг байдлаар ашиглах болно нэг (модаль бус) цонхтой;
  2. Харилцах цонхны навигацийн бүх давуу талыг хассаны дараа бид WM_KEYDOWN/WM_KEYUP-ыг харагдацад нэмэх хэрэгтэй (зөвхөн цонхны хувьд, хүүхдийн удирдлагад биш);
Энэ үе шатанд бүх хичээлүүд дуусч, хоол эхэлдэг: Winapi стандарт харилцах цонхонд гарны үйл явдлыг хэрхэн зохицуулах вэ?
Энэ бол Google эсвэл Интернет дээр нийтлэгдсэн хамгийн эхний зүйл юм: тэдний мянга мянган. Санал болгож буй шийдлийн тухай (хамгийн гол нь RegisterHotKey-ийг дэд ангилахаас өмнө миний дээр бичсэн харилцан ярианы ангиллыг бий болгох шаардлагатай. Эндээс би "хамгийн богино" аргуудыг сурах болно: vikorize Windows Hooks).

Хичээл, видео бичлэгт юу дутагдаж байгааг ярих цаг болжээ.

Дүрмээр бол (дүрмээр бол! Хэрэв хэн нэгэн илүү ихийг хүсч байвал та ангиа харилцан ярианд бүртгүүлж, ингээд үргэлжлүүлж болно. Хэрэв танд хамаагүй бол би энэ нийтлэлийг нэмж болно) WM_KEYDOWN хэрэв та даралтыг дуусгахыг хүсч байвал үүнийг хүсч байна. оффис дээр шаардлагатай хяналтаас үл хамааран функцийг сонгох түлхүүр - энэ нь. Энэ нь тухайн яриа хэлэлцээний чухал үүрэг юм. Хэрэв тийм бол WinAPI-ийн бидэнд заадаг баялаг боломжуудыг яагаад хурдан танилцуулж болохгүй гэж: TranslateAccelerator.

Використоор дамжуулан яг нэгхурдасгуурын хүснэгт, тэр ч байтугай үндсэн цонх. Үнэнийг хэлэхэд, GetMessage-ийн циклийн нэг л цикл байдаг бөгөөд зөвхөн нэг хүснэгт байдаг. Тэд хаашаа явах ёстой вэ?

Үнэн хэрэгтээ GetMessage-гогцоонууд байж болно оруулсан хувь нэмэр. PostQuitMessage-ийн тайлбарыг дахин нэг удаа гайхшруулцгаая:

Функцууд PostQuitMessage нь WM_QUIT мессежийг хэлхээний мессежийн дараалалд байршуулж, шууд буцаана;
Би мессеж авсан:
Хэрэв функц нь WM_QUIT мессежийг шинэчлэх юм бол буцах утга нь тэг болно.
Тиймээс GetMessage-loop-ээс гарах нь цонхны процедурт PostQuitMessage-г дууддаг. Энэ юу гэсэн үг вэ?

Бид чадна арьсны модаль бус Энэ бол манай программын өөрийн эрчим хүчний циклийг бий болгох цонх юм. Хэрэв DialogBoxParam бидэнд тохиромжтой бол, учир нь Бид өөрсдийн энергийн эргэлтийг эргүүлэх боломжгүй юм. Гэсэн хэдий ч, хэрэв та CreateDialogBoxParam-ээр харилцах цонх эсвэл CreateWindow-ээр дамжуулан цонх үүсгэвэл өөр давталт ажиллуулж болно. Энэ нь ирэхэд арьсныЭнэ төрлийн харилцан ярианы хувьд бид PostQuitMessage дээр дарах үүрэгтэй:

HWND hMainWnd = Цонх үүсгэх(...); HACCEL hAccel = Load Accelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); BOOL bRet = 0; байхад (bRet = GetMessage(&msg, nullptr, 0, 0)) ( хэрэв (-1 == bRet) завсарлага; хэрэв (!TranslateAccelerator(hMainWnd, hAccel, &msg)) (хэрэв (!IsDialogMessage(hMainWnd) TranslateMessage(&msg)) ; DispatchMessage(&msg); ) ))) // .... hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), hwnd, MyDialogBoxProc), HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR_DIALOGALOG)); wnd, FALSE);// (bRet = GetMessage(&msg, nullptr, 0, 0)) (хэрэв (-1 == bRet) завсарлага; хэрэв (!TranslateAccelerator(hDlg, hAccel)) харилцах цонх нь модаль байдаг тул эх цонхыг идэвхгүй болгох. , &msg)) (хэрэв (!IsDia, &msg)) ( TranslateMessage(&msg); DispatchMessage(&msg); ) ) ) EnableWindow(hwnd, fSavedEnabledState); // Эцэг эхийн цонхыг идэвхжүүлнэ. wparam, LPARAM lparam) (switch(umsg) (тохиолдол WM_CLOSE: (// EndDialog(hwnd, 0)); - ИНГЭЖ БОЛОХГҮЙ! // EndDialog нь зөвхөн DialogBox(Param) DestroyWindow(hwnd) ашиглан үүсгэсэн харилцах цонхыг өөрчлөхөд л зөв; завсарлага; ) тохиолдол WM_DESTROY: ( PostQuitMessage(0); завсарлага; ) // .... ) 0 буцаана; )
Эрхэм хүндэтгэе: одоо манай програмын шинэ арьсны цонхны хувьд бид боловсруулахаасаа өмнө нэмж болно Власнухурдасгуурын хүснэгт. WM_QUIT GetMessage-г харилцах цонхны давталтаас устгадаг ба гаднах давталт ажиллахгүй. Чи яагаад ийм их догдолж байгаа юм бэ?

Баруун талд нь одоогийн мөчлөг нь бидний процедур гэж нэрлэгддэг DispatchMessage товшилт дээр "босох" бөгөөд түүний хүчийг хэрхэн эргүүлэх вэ дотоодЭнэхүү DispatchMessage-тэй GetMessage-ийн гогцоо өөрөө. Сонгодог вики хавсралтууд (DispatchMessage дээр). Тиймээс гаднах давталт нь WM_QUIT-г цуцлахгүй бөгөөд энэ үе шатанд дуусна. Бүх зүйл хэвийн явагдаж байна.

За, энд зарим нэг дутагдал байна:
Арьс нь энэ мөчлөгийг мэддэг зөвхөн "таны" цонхны хувьд. Энд байгаа бусад хүмүүсийн талаар бид мэдэхгүй. Энэ нь хэрэв өөр мөчлөг энд гарч ирвэл бүгд TranslateAccelerator/IsDialogMessage хосыг ашиглан мессежээ боловсруулах шаардлагатай болно гэсэн үг юм.

За, та бүхний хүндэтгэлийг буцаан авч, манай хөтөлбөрийн бүх үр дүнг танд мэдэгдэхийн тулд бүх зүйлийг зөв боловсруулах талаар бичиж, шийдэх цаг болжээ. Нэг урсгалын шагнал бага байдаг гэдгийг би хүндэтгэхийг хүсч байна. Учир нь Хэрэв арьсны урсгал нь түүний бүтцийг таних боломжийг олгодог бол арьсны урсгал нь түүний бүтцийг бий болгох шаардлагатай болно. Кодын өчүүхэн өөрчлөлтөөс ч айх.

Робимо үзэсгэлэнтэй

Учир нь Хэрэв даалгавраа зөв тавих нь шийдлийн тал нь юм бол би эхлээд даалгавраа зөв тохируулах хэрэгтэй.

Юуны өмнө, энэ нь зөвхөн логик байх болно илүү идэвхтэйБи одоо мэдэгдэл хүлээн авч байна. Тобто. Идэвхгүй цонхны хувьд бид хурдасгуурыг орчуулж, IsDialogMessage руу мэдэгдэл илгээдэггүй.

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

Цонхны тодорхойлогчийг хурдасгуурын хүснэгтийн тодорхойлогч руу буулгах энгийн std::map бүтээцгээе. Тэнхлэг нь дараах байдалтай байна.

Std :: газрын зураг l_mAccelTable;
Үүсгэсэн цонхнуудын ертөнцөд бид таны дуртай хүснэгтэд тодорхойлогч бүхий шинэ цонхыг үргэлжлүүлэн нэмэх болно (эсвэл тэг, учир нь ийм боловсруулалт хийх шаардлагагүй).

Bool Addacceledators (Hwnd Hwnd, HALDHWOW (HINDWAND) (ХИЧЭЭЛ (ХИЧЭЭЛИЙН) ХУДАЛДАН АВНА (ХИЧЭЭЛ (ХИЧЭЭЛ) hWnd, хурдатгал)
Тэгээд цонхоо хаасны дараа яв. Тэнхлэг нь дараах байдалтай байна.

Хүчингүй DelAccel(HWND hWnd) ( std::map :: давтагч намайг = l_mAccelTable.find(hWnd); if (me != l_mAccelTable.end()) ( if (me->секунд) ( DestroyAcceleratorTable(me->second); ) l_mAccelTable.erase(me); ) )
Одоо бид шинэ харилцах цонх/цонх үүсгэх үед AddAccelerators (hNewDialog, IDR_MY_ACCEL_TABLE) дээр дарна уу. Хэрхэн хаах вэ: DelAccel(hNewDialog).

Бидэнд шаардлагатай тодорхойлогчдын жагсаалт байна. Бид үндсэн боловсруулалтын гогцоог хэрхэн өөрчилдөг вэ:

// ... HWND hMainWnd = Цонх үүсгэх(...); AddAccelerators(hMainWnd, IDR_ACCELERATOR); BOOL bRet = 0; байхад (bRet = GetMessage(&msg, nullptr, 0, 0)) (хэрэв (-1 == bRet) тасарвал; хэрэв (!HandleAccelArray(GetActiveWindow(), msg)) ( TranslateMessage(&msg); DispatchMessage ) // .. .
Хамаагүй дээр! HandleAccelArray-д юу байгаа вэ, GetActiveWindow()-д юу байна вэ?

Бага зэрэг онол:

GetForegroundWindow болон GetActiveWindow идэвхтэй цонхны бариулыг эргүүлэх хоёр функц байдаг. Эхнийх нь нөгөөгөөсөө чухал болохыг нөгөөгийнхөө тайлбарт бүрэн дүрсэлсэн болно.

Буцах утга нь дуудаж буй хэлхээний мессежийн дараалалд хавсаргасан идэвхтэй цонхны бариул юм. Үгүй бол буцах утга нь NULL байна.
Хэрэв та эхлээд системийн аль ч цонхны тодорхойлогчийг эргүүлэх юм бол бусад нь зөвхөн болно використын үг бидний урсгалыг хэрхэн мэдээлэх вэ. Учир нь Бид зөвхөн урсгалаараа (мөн бидний өдрийг хүртэл дэмий үрэгдэх хүмүүс) үргэлжлүүлэн амьдрах болно, тэгвэл бид үлдэх болно.

Тиймээс идэвхтэй цонхон дээрх тодорхойлогчоор дамждаг HandleAccelArray тэнхлэг нь манай газрын зураг дээр бас харагдах бөгөөд байгаагаараа TranslateAccelerator-ийн орчуулга руу мессеж илгээж, дараа нь (эхнийх нь хийгээгүй юм шиг) IsDialogMessage дотор шаардлагатай )-г нэмнэ үү. Хэрэв мессеж хараахан илгээгдээгүй бол ХУДАЛ болгож, TranslateMessage/DispatchMessage стандарт горимыг ашиглана уу.

Энэ нь дараах байдалтай харагдаж байна.

BOOL HandleAccelWindow(std::map ::const_iterator mh, MSG & msg) ( const HWND & hWnd = mh->first; const HACCEL & hAccel = mh->секунд; хэрэв (!TranslateAccelerator(hWnd, hAccel, & msg))) ( // Орчуулахын тулд мессеж биш хэрэв (!IsDialogMessage(hWnd, &msg)) ( // тэгэхээр, үндсэн зүйл нь ХУДАЛ буцаана; ) ) // за, мессеж орчуулагдсан.(HWND hActive, MSG & msg) (хэрэв (!hActive) FALSE буцаана; // идэвхтэй цонх байхгүй. std::map хийх зүйл алга ::const_iterator mh = l_mAccelTable.find(hActive); if (mh != l_mAccelTable.end()) ( // Ойлголоо! Идэвхтэй цонхны буцах хэсэгт энэ мессежийг орчуулж үзээрэй HandleAccelWindow(mh, msg); ) FALSE буцаана; )
Одоо хүүхэд бүр өөрийн дуртай хурдасгуурын хүснэгтээ нэмж, WM_COMMAND-г шаардлагатай кодоор тайвнаар барьж, оруулах эрхтэй.

WM_COMMAND кодын нэг мөрийн талаар өөр юу байна вэ?

TranslateAccelerator дээрх тайлбар:
Мессеж бүхий илгээх функц нь цэс эсвэл удирдлага гэсэн үг гэдгийг тодорхой болгохын тулд wParam параметртэй WM_COMMAND эсвэл WM_SYSCOMMAND мессеж бүхий өндөр үр дүнтэй үг нь 1 утгыг агуулна.
WM_COMMAND боловсруулах код дараах байдалтай байна.

Switch(HIWORD(wParam)) ( BN_CLICKED: // Товчнууд/цэсүүдээс команд (шилжүүлэлт(LOWORD(wParam))) ( IDC_BUTTON1: DoButton1Stuff(); завсарлага; IDC_BUTTON2: DoButton2Stuff ) завсарлага; ) )
Одоо та үүнийг дараах байдлаар бичиж болно.

Switch(HIWORD(wParam)) ( 1-р тохиолдол: // хурдасгагч BN_CLICKED // Товчлуур/цэсүүдээс команд ( switch(LOWORD(wParam))) ( IDC_BUTTON1: DoButton1Stuff(); завсарлага; IDC_BUT // ... ) завсарлага ;))
Тэгээд одоо, ижил fceux руу эргэж, нэмсэн зүгээр л нэг эгнээТовчлуурын командыг боловсруулах кодонд бид дараахь зүйлийг устгана: гараас дибаг хийгчийг ашиглана уу. Толгойн гогцооны ойролцоо жижиг бүрхүүл, тодорхой төрлийн VK_KEY => IDC_DEBUGGER_BUTTON хурдасгуурын шинэ хүснэгтийг нэмэхэд хангалттай.

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

P.P.S.: Учир нь DialogBox/DialogBoxParam нь тэжээлийн циклийг эргүүлж, дараа нь тэдгээрээр дамжуулан харилцан яриаг дуудах үед хурдасгуурууд ажиллахгүй бөгөөд бидний цикл (эсвэл мөчлөг) "сул зогсолт" байна.

P.P.P.S.: HandleAccelWindow картыг дарсны дараа l_mAccelTable-г өөрчилж болно, учир нь TranslateAccelerator эсвэл IsDialogMessage DispatchMessage дээр дарснаар та манай процессор дээр AddAccelerators эсвэл DelAccel-д нэгдэж болно! Тиймээс эдгээр функцийг үл тоомсорлохгүй байх нь дээр.

Та кодыг оруулж болно. Энэ нь стандарт MS VS 2017 загвараас үүсгэсэн код дээр үндэслэсэн болно.

Шошго: шошго нэмэх

C WinAPI нь үйлдлийн системд байдаг Microsoft програмын интерфейсийн (API) үндсэн багц юм.Эхний хувилбар нь Win32 API гэж нэрлэгддэг байсан.

Оруулна уу

WinAPI нь Windows программ үүсгэхэд хэрэглэгддэг хэрэглээний програмчлалын интерфейс юм. Эхлэхийн тулд хөгжүүлэгч нь өмнө нь Платформ SDK гэгддэг Windows SDK-г ашиглах ёстой.

Толгой файл, номын сан, зураг, баримт бичиг, программ боловсруулахад ашигладаг хэрэгслүүдийг нэгтгэнэ. C болон C++ хэл дээр хэлний програмчлалд зориулсан API. Энэ нь компанийн үйлдлийн системд нэмэлт програм үүсгэх хамгийн шууд арга юм.

WinAPI-ийн тусламжтайгаар та үүнийг хэд хэдэн хэсэгт хувааж болно:

    үндсэн үйлчилгээ;

    аюулгүй байдал;

  • Користувалницкийн интерфейс;

    мультимедиа;

    Windows бүрхүүл;

    Мережевийн үйлчилгээ.

Суурь үйлчилгээ нь үндсэн нөөцөд нэвтрэх боломжийг олгоно. Үүнд WinAPI, файлын систем, төхөөрөмжүүд, процессууд, хэлхээнүүд, бүртгэл, алдаа боловсруулах функцууд орно. Хамгаалалтын талбар нь нэвтрэлт танилт, зөвшөөрөл, криптограф болон аюулгүй байдалтай холбоотой бусад ажлуудад зориулсан интерфейс, объект болон бусад програмчлалын элементүүдийг агуулдаг. График дэд систем нь монитор, принтер болон бусад дэлгэцийн төхөөрөмж дээр график харуулах функцээр хангадаг. Koristuvach интерфэйс нь koristuvach-ийн цонх, элементүүдийг үүсгэх функцээр хангана.

Мультимедиа бүрэлдэхүүн хэсэг нь видео, аудио, оролтын төхөөрөмжтэй ажиллах хэрэгслүүдээр хангадаг. Бүрхүүлийн интерфэйсийн функцууд нь программуудад үйлдлийн системийн бүрхүүлээс өгсөн функцүүдэд хандах боломжийг олгодог. Мережевийн үйлчилгээнүүд нь Windows-д боломжтой хамгийн дээд хэмжээгээр нэвтрэх боломжийг олгодог.

Бүрэлдэхүүн хэсгүүд

WinAPI-г ажиллуулснаар та Windows API-ийн үндсэн боломжуудыг ашиглах боломжтой бөгөөд үүнийг долоон ангилалд хувааж болно. Тэдний илтгэлийн арьсыг харцгаая.

Үндсэн үйлчилгээнүүд нь Windows дахь системийн үндсэн нөөцөд хандах боломжийг олгодог. Хэрэглээ: файлын систем, захын төхөөрөмжүүд, процессууд, системийн бүртгэл, цөмийн системд хандах. Эдгээр функцууд нь 16 битийн системүүдийн хувьд kernel.exe, krnl286.exe эсвэл krnl386.exe, 32 битийн системүүдийн хувьд kernel32.dll болон advapi32.dll файлд хадгалагддаг.

График интерфэйс нь монитор, принтер болон бусад захын төхөөрөмж дээр харуулах нөөцөд хандах боломжийг олгоно. Энэ нь 16 битийн системд gdi.exe, 32 битийн систем дээр gdi32.dll файлд хадгалагддаг.

Хэрэглэгчийн интерфейсийн интерфэйс нь товчлуур, гүйлгэх зэрэг үндсэн элементүүдийн харагдах байдал, гар, хулганы тухай мэдээлэл, түүнчлэн тэдгээртэй холбоотой функцүүдээр тодорхойлогддог. Эдгээр функцууд нь 16 битийн систем дээрх user.exe файлд, 32 битийн систем дээрх user32.dll comctl32.dll файлд хадгалагддаг. XP хувилбараас эхлэн удирдлагыг comctl32.dll гэж бүлэглэсэн.

Нууц харилцан яриа - Файл нээх, хадгалах, өнгө, фонт сонгох өгөгдлийг харуулах. Энэ файл нь 16 битийн систем дээр comdlg.dll, 32 битийн систем дээр comdlg32.dll байна.

Windows Shell нь WinAPI бүрэлдэхүүн хэсэг бөгөөд программуудад үйлдлийн системийн бүрхүүлээс өгсөн функцүүдэд хандах боломжийг олгодог.

Сүлжээний үйлчилгээ нь үйлдлийн системийн хамгийн их чадамжид хандах боломжийг олгодог. Түүний дэд бүрэлдэхүүн хэсгүүдэд NetBIOS, Winsock, RPC орно. Хуучин хувилбарууд нь NetDDE-тэй.

Хувилбарууд

Win16, Win32, Win32s нь хэрэглээний программ хангамжид Windows-ийн гэр бүлийн янз бүрийн үйлдлийн системүүдийн функцийг гүйцэтгэх боломжийг олгодог бүрэлдэхүүн хэсгүүдийн стандарт багц юм.

Win16-ийн залгамжлагч Win32 нь 1993 онд Windows NT, 2000, 95 зэрэг Windows-ын гэр бүлийн 32 битийн бүтээгдэхүүнүүдэд танилцуулагдсан. Энэхүү програм хангамжийн интерфейс нь Kernel32.dll, User32.dll болон GDI32.dll2 гэсэн гурван програм хангамжийн санг хэрэгжүүлдэг. Win32-ийн ижил функцууд нь Windows-ийн бүх бүтээгдэхүүнд байдаг бөгөөд бүтээгдэхүүнээс хамааран эдгээр функцийг нэмэх нь үйлчилгээний асуудал үүсгэж болзошгүй.

Win32-ийн боломжууд нь программ хоорондын харилцаа холбоо, процессын удирдлага, компьютерийн файлууд, принтерүүд, серверүүд болон холбооны портуудыг багтаадаг.

Тодорхойлолт

WinAPI нь Windows үйлдлийн системийн програмчлалын интерфейсийн хийсвэр тодорхойлолт юм. Функц, холболт, бүтэц, өгөгдлийн төрөл, макро, тогтмол болон бусад програмчлалын элементүүдийн мэдэгдлээс бүрдэнэ. WinAPI нь толгой хэсэгт дүрслэгдсэн бөгөөд Windows C толгой хэсэгт байрладаг.WinAPI функцийн албан ёсны хэрэгжилт нь динамик номын санд (DLL) байрладаг: жишээлбэл, систем дэх kernel32.dll, user32.dll, gdi32.dll болон shell32.dll. лавлах. Windows API-ийн гуравдагч этгээдийн хэрэгжүүлэлтүүд байдаг: ялангуяа Wine төсөл болон ReactOS төсөл.

Windows API нь динамик объект юм. Үйлдлийн системийн шинэ хувилбар болон шинэ шинэчлэлтийн багц бүрээр функцүүдийн тоо аажмаар нэмэгдэж байна. Мөн серверийн хувилбарууд болон үйлдлийн системийн ширээний хувилбаруудын хооронд чухал ялгаа бий. Эдгээр чиг үүргийг албан ёсоор баримтжуулаагүй болно.

Пеллес С

Pelles C нь програм хангамжгүй програм бөгөөд хамгийн хурдан C хөрвүүлэгч бөгөөд Си хэлний програмчлалын нэгдсэн хөгжүүлэлтийн хөдөлгүүр (IDE) юм.32 битийн Windows (x86) болон 64 битийн Windows (x64)-ийг дэмждэг. C99, C11 стандартуудыг хэрэгжүүлдэг. Pelles нь нөөцийн засварлагч, битмап зураг, дүрс, курсор засварлагч, арван зургаан хогийн засварлагчийг агуулж болно. Шведийн жижиглэнгийн худалдаачин Pelle Orinius илчилсэн. Эмхэтгэгчийн нэр нь зохиогчийнх нь нэрийг агуулдаг. SDK-д хавсаргасан программист үүсгэсэн программыг нэмэлт суулгалгүйгээр шууд хэвлэх боломжтой.

Зорилготой архитектур

Windows API програмуудыг үүсгэхийн тулд та Microsoft өргөтгөлүүдийг идэвхжүүлэх хэрэгтэй. Үүний цаана эвдэрсэн бүтэцтэй C WinAPI программ шиг алдааны тухай мессежийг хөрвүүлэгч хардаг өмхий үнэртэй: үхлийн алдаа #1014: #алдаа: "Зорилтот архитектур байхгүй." Майкрософт өргөтгөлийг идэвхжүүлэхийн тулд төслийн параметрүүд рүү очоод "Хөрөнгө оруулагч" табыг сонгоно уу. Энэ таб дээр "Microsoft өргөтгөлүүдийг идэвхгүй болгох" сонголтыг идэвхжүүлсэн.

MSDN

Энэ бол Windows суулгах төв портал юм. Энэ бол Microsoft-ын янз бүрийн хэрэгслээс програм боловсруулахтай холбоотой агуу материалуудын цуглуулга юм. Ширээний программуудын хөгжүүлэлтийн баримт бичиг, Windows API-ийн жагсаалт бүхий иж бүрэн мэдээллийн сан.

WinAPI C дахь Zastosuvannya DLL

Дэвшилтэт элементүүдийн номын сан нь мөр, цонхны үзүүлэлт, хэрэгслийн мөр, таб зэрэг үйлдлийн системийн дэвшилтэт функцүүдэд хандах боломжийг олгоно. Эдгээр тушаалууд нь 16 битийн систем болон comctl32.dll-ийн commctrl.dll номын санд байрладаг бөгөөд үйлчлүүлэгчийн интерфейстэй хамт бүлэглэгддэг.

DLL нь Windows програмын хэд хэдэн код, процедурыг хадгалахад ашиглагддаг динамик номын сангийн файлын формат юм. DLL файлууд нь хэд хэдэн программууд мэдээлэлдээ шууд нэвтэрч, улмаар санах ойг хэмнэдэг байдлаар бүтээгдсэн. Хэрэглэгчдэд кодыг өөрчлөхгүйгээр олон программ дээр засварлах боломжийг олгоно. DLL номын сангуудыг Lib 3.00-д зориулсан статик, vikorist MSIL Disassembler эсвэл DLL болгон хөрвүүлэх боломжтой.

Winapi Yak INTERFAS нь Windows Proponovs-ийн үерийн маягтуудад зориулсан хэрэглээний туршилтын INTERFAS нь Яки тэдний шинж тэмдгүүдийг хадгалах боломжийг олгодог бөгөөд энэ нь зүгээр л Nizorivniye хөтчүүдийн үйл ажиллагаанд график илнтерфисын хоригдлуудад файлуудыг оруулах явдал юм.

WinAPI программчлалыг эхлүүлэхийн өмнө та Windows дээрх кодын дунд хэсгийг тохируулах хэрэгтэй. Хэдийгээр энэ нь Линуксийн түгээлт биш ч нэмэлт програмуудыг үүсгэхэд зориулагдсан хөрвүүлэгчгүй. Кодыг эмхэтгэх дараах сонголтуудыг харцгаая.


Windows-д зориулсан хөгжүүлэгчийн иж бүрдэл нь Wikimedia API болон холбогдох технологиудыг ашиглан программ хангамж бүтээх боломжийг хөгжүүлэгчдэд олгодог баримт бичиг, хэрэгслээр хангадаг.

Windows API - үйлдлийн системийн функцүүдийн багц

API товчлол нь олон шинэхэн програмистуудад тодорхойгүй, ойлгомжгүй мэт санагддаг. Үнэн хэрэгтээ, Application Programming Interface (API) нь нэмэлт үйлдвэрлэгчдийн ашиглаж болох бэлэн функцүүдийн багц юм. Албан ёсны утгаараа энэ ойлголт нь өмнө нь ихэвчлэн дэд программуудын номын сан гэж нэрлэгддэг байсантай дүйцэхүйц юм. Гэсэн хэдий ч API-ийн дагуу ийм номын сангийн тусгай ангилал байдаг гэдгийг анхаарна уу.

Хөгжүүлэлтийн явцад тодорхой программыг хэрэгжүүлэхэд шаардлагатай тодорхой дотоод функцүүдийн багцыг эцсийн хэрэглэгчдэд зориулж бүрдүүлдэг бөгөөд үүнийг MyApplication API гэж нэрлэдэг. Гэсэн хэдий ч эдгээр функцийг бусад програм, түүний дотор бусад програмуудыг бий болгоход үр дүнтэй ашиглаж болохыг олж мэдсэн. Зохиогчид бүтээгдэхүүнээ борлуулах стратеги дээр үндэслэн хоол тэжээлийг ямар арга замаар сонгодог вэ: яагаад тэд гадны хэрэглэгчдэд аль багцыг ашиглахыг зөвшөөрдөг вэ? Хэрэв батлагдсан бол програм хангамжийн багцыг эерэг шинж чанар болгон тайлбарлахад "Багц нь API функцүүдийн цогц багцыг агуулдаг" (эсвэл нэмэлт мөнгө) гэсэн хэллэгийг агуулна.

Тиймээс ихэвчлэн API-ийн дагуу нэг програмын нэг хэсэг болох олон функцууд байдаг боловч бусад програмуудад ашиглах боломжтой байдаг. Жишээлбэл, Excel нь эцсийн хэрэглэгчийн интерфэйсээс гадна Excel-ийн API функцүүдтэй бөгөөд жишээлбэл, VB ашиглан үүсгэсэн програмуудаар хандаж болно.

Windows API нь үйлдлийн системийн нэг хэсэг болох функцүүдийн багц бөгөөд нэгэн зэрэг бусад програмууд, тэр дундаа VB ашиглан бичсэн програмуудад хандах боломжтой юм. Энэ төлөвлөгөө нь системийн BIOS/DOS хүчингүй болгох багцтай бүрэн төстэй бөгөөд энэ нь үнэндээ DOS API юм.

Windows API функцийн давуу тал нь нэг талаас DOS-ээс хамаагүй өргөн, нөгөө талаас хуучин үйлдлийн систем дээрх программуудад ашиглах боломжтой компьютерийн нөөцийг шууд хянах олон боломжуудыг агуулдаггүй. Нэмж дурдахад Windows API-тай холбогдох нь нэмэлт процедурын параметрүүд дээр суурилдаг бөгөөд DOS функцэд Interrupt хэмээх тусгай процессорын машины командаар ханддаг.

VB програмистуудад хамгийн их шаардлагатай Win API

VB нь янз бүрийн үүрэг гүйцэтгэдэггүйгээс үл хамааран илүү их эсвэл бага ноцтой хөгжлийн явцад тэдний чадвар нь шаардлагатай даалгавруудыг биелүүлэхэд хангалтгүй байдаг нь илчлэгдсэн байдаг. Энэ тохиолдолд шинэхэн програмистууд ихэвчлэн VB-г алдаж, хэрэглүүрийг өөрчлөх талаар бодож эхэлдэг бөгөөд тэдний компьютер маш их зардалтай тул үүнийг хурдан оруулах шаардлагатай болдог.

Win API-тай танилцах үед системийн тодорхой горимд боловсруулагдсанаас өөр зүйл биш, зөвхөн энэ хэлний синтаксийн дагуу хэрэгждэг олон VB функцууд байдаг. Шуурхай API-ийн хэрэгцээнд үндэслэн боломжтой сонголтууд нь:

  1. VB функц хэлбэрээр ерөнхийдөө хэрэгждэг API функцууд. Цаг хугацаа багагүй, энэ тохиолдолд API зогсонги байдалд шилжих шаардлагатай байж магадгүй бөгөөд ингэснээр бүтээмжийг хурдан нэмэгдүүлэх боломжтой болно (шилжсэн параметрүүдэд шаардлагагүй өөрчлөлт оруулахгүй байхаас бусад).
  2. Үүсгэсэн VB функцууд нь зөвхөн API функцүүдийн нэг хэсэг болгон хэрэгждэг. Энд илүү энгийн сонголт байна. Жишээлбэл, CreateDirectory API функц нь VB MkDir оператортой харьцуулахад илүү их боломжуудтай.
  3. VB хэлний одоогийн хувилбарт аналоггүй олон тооны API функцууд байдаг. Жишээлбэл, VB ашиглан лавлахыг устгах боломжгүй - үүний тулд та DeleteDirectory функцийг ашиглах хэрэгтэй.

Зарим API функцууд (тэдгээрийн зарим нь Win API-д тийм ч ач холбогдолгүй байдаг) VB програмуудаас хэд хэдэн хэлний интерфейсээр дамжуулан хандах боломжгүй, жишээлбэл санах ойн хаягтай ажиллах чадваргүйгээс болж байгааг тэмдэглэх нь зүйтэй. Гэсэн хэдий ч хэд хэдэн тохиолдолд энгийн бус програмчлалын техникүүд тусалж чадна (ижил хаягуудын хувьд).

Зохиогчийн онцгой санаа бол хувилбарыг VB-ийн ашигладаг функцүүдийн хувилбар болгон өргөжүүлэхийн оронд хамгийн түгээмэл API функцүүдийн талаар сайн тайлбар өгөх болно. Үүний зэрэгцээ, хөгжүүлэгчид өргөтгөсөн функц бүхий шинэ хувилбар гарч ирэхийг хүлээх хэрэггүй, харин анхны Win API-ийн нөөцийг анхаарч үзэхийг хүсч байна - таны чадварууд тодорхой байна. хэрэгцээг 1991 оны ї VB 1.0 хувилбарт аль хэдийн хэрэгжүүлж болох юм.

Yak vivchati Win API

Win32 API-ийн функцүүдийн тоог 10 мянга орчим гэж тооцдог гэдгийг санах нь тийм ч хялбар биш юм (Microsoft гэх мэт нарийн тоог хэн ч мэдэхгүй).

VB агуулах (хувилбар 4-6) нь Win API - WIN32API.TXT-ийн тайлбар бүхий файлыг агуулдаг (түүний хэрэгжилтийн тайланг дараа зарлах болно). Юуны өмнө, энэ тусламжтайгаар та дараах mnemonic нэрсээс бусад энэ болон бусад функц, параметрүүдийн утгын талаарх мэдээллийг харах боломжтой бөгөөд өөрөөр хэлбэл энэ файлын функц нь ижил биш юм. Өнөө үед (азаар бол) VB 3.0 нь Win16 API функцийг тодорхойлсон концепцын нотолгооны тусгай файлуудтай байсан. V.4.0-д энэхүү үнэ цэнэтэй мэдээллийг гарын авлагын интерфейсээр дамжуулан авах боломжтой.

Win32 API-ийн талаарх нэмэлт мэдээллийг өмнөх Platform Software Development Kit-аас авах боломжтой бөгөөд үүнийг VB 5.0, 6.0 Enterprise Edition, Office 2000 Developer Edition-д багтсан MSDN Library CD-ээс авах боломжтой. Гэсэн хэдий ч тэндээс хэрэгтэй мэдээллээ олж, түүнд хандах нь тийм ч хялбар биш юм. Тэнд дурдсан бүх тайлбарыг бүхэлд нь С.

VB орчинд API програмчлалын талаарх дэлхийн хамгийн танил болсон танилцуулга бол Америкийн нэрт шинжээч Даниел Эпплмэний ном юм. 1993 оноос хойш Дан Апплманы Windows API-д зориулсан Visual Basic программистын гарын авлага (Win16, Win32, VB-ийн олон зуун өөр хувилбаруудад зориулсан) цуврал нь VB програмистуудын хувьд байнга хамгийн их борлуулалттай болсон. 1997 онд хэвлэгдсэн Дэн Эплмэний VB 5.0 программистын гарын авлага Win32 API номыг нэгэн жижиг хотын номын дэлгүүрийн талаар мэддэг найз нь АНУ-аас зохиолчид авчирсан.

1500 гаруй хуудастай энэхүү номонд VB хэл дээрх API програмчлалын дэвшилтэт арга техник, мөн 900 гаруй функцийг багтаасан болно. CD-нд номын бүрэн эх бичвэр болон бүх программ хангамж, мөн хоёр дахь хувилбарт хүрч чадаагүй хэд хэдэн нэмэлт хэсгүүд байх болно. 1999 онд Дэн Эпплман шинэ номоо гаргасан бөгөөд Дан Эпплманы Win32 API Puzzle Book and Tutorial for Visual Basic программистуудад зориулсан зааварчилгаа нь өөр 7600 функцын тоймыг багтаасан (гэхдээ тайлагнах самбар биш).

Win API ба динамик холбоос номын сан (DLL)

Динамик DLL сангууд болох Win API хэрэгжүүлэлтийн багц. Дараа нь бид Win API агуулахад багтсан номын сангуудын хэрэглээнд VB-ийн дунд DLL-г суулгах технологийн талаар ярих болно. Гэсэн хэдий ч DLL-ийн тухай ярихдаа маш их хүндэтгэлтэй хандах хэрэгтэй.

Энэ тохиолдолд DLL-ийн дагуу бид давхар динамик номын сангийн уламжлалт хувилбарыг хүндэтгэх боломжтой бөгөөд энэ нь шаардлагатай процедурууд - дэд програмууд эсвэл функцууд руу шууд хөрвүүлэх боломжийг олгодог (VB төслийн дундах процедурууд дээр дарахад хүлээгдэж буйтай ижил төстэй) . Ийм сангуудыг бусад хэрэгслийг ашиглан үүсгэж болно: VC++, Delphi, Fortran, VB (7.0 хувилбар дээр гарч байгаа зүйлээс хамаарна) - үлдсэн хэсэг нь ActiveX DLLгүйгээр ажиллах боломжтой бөгөөд тэдгээрт хандах хандалтыг OLE Automation интерфейсээр тохируулдаг.

Динамик номын сангийн файлууд нь өргөтгөл.DLL-г агуулж болох ч энэ нь заавал байх албагүй (Win16-ийн хувьд өргөтгөл.EXE ихэвчлэн гацдаг байсан); Гадны төхөөрөмжийн драйверуудыг нэмэлт DRV дор жагсаасан болно.

Өмнө дурьдсанчлан, системийн каталогт хадгалах боломжтой байхын тулд Windows API функцууд болон файлуудын яг тоог тодорхойлох нь чухал юм. Энэхүү төлөвлөгөө нь үйлдлийн системийн цөм хүртэлх номын сангийн агуулах, үндсэн нэмэлт функц бүхий үндсэн номын сангуудыг харах нь дээр.

Тэгээд одоо би баяртай байна.

1. DL зарын зөв форматыг дагаж мөрдөнө үү L-процедурууд

DLL процедур хүртэлх программын шатлал нь Visual Basic-ийн "анхдагч" процедуртай ижил харагдаж байна, жишээлбэл:

DllName руу залгах ([аргументын жагсаалт])

Гэсэн хэдий ч, гадаад DLL функцуудыг (Win API-г оруулаад) ашиглахын тулд Declare мэдэгдлийг ашиглан програмыг дуудах ёстой бөгөөд энэ нь дараах байдалтай байна.

Дэд процедурын нэрийг зарлах Lib _ “Номын сангийн нэр” _ [([Аргументуудын жагсаалт])]

Функц функцын нэрийг зарлах _ Lib “Номын сангийн нэр” _ [([Аргументуудын жагсаалт])]

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

Ихэнх гадаад функцууд нь модулийн Ерөнхий мэдэгдлийн хэсэгт байрладаг. Хэрэв та үүнийг маягтын модульд байрлуулсан бол Private түлхүүр үгийг зааж өгөх ёстой (энэ нь зөвхөн модулийн дунд байх болно) - энэ нь маягтын модулийн бүх процедурт ижил байна.

Win32 API хэрэгжүүлэлтийн багц нь зөвхөн функцээр хязгаарлагддаг (Win16 API нь маш олон дэд програмуудтай). Энэ нь ялангуяа үйл ажиллагааны гүйцэтгэлийн кодыг ихэвчлэн буцаадаг Long төрлийн функцүүдэд үнэн юм.

Declare оператор нь DOS-д зориулагдсан MS Basic программд аль хэдийн гарч ирсэн бөгөөд дотоод процедурыг төсөлд дамжуулахад ашиглагдаж байсан. Visual Basic-д үүнийг хийх шаардлагагүй, учир нь дотоод журмын мэдэгдэл нь тэдгээрийн Дэд болон Функцийн тайлбарыг автоматаар тодорхойлдог. Basic/DOS-д тохируулсан шинэ тайлбар нь процедур хаана байрладаг номын сангийн файлын нэрийг зааж өгөх ёстой. Wip API сангууд нь Windows системийн лавлах хэсэгт байрладаг бөгөөд зөвхөн файлын нэр л шаардлагатай. Хэрэв та DLL дээр ажиллаж байгаа бол итгэлтэй байхын тулд тухайн файл руу шинэ зам бичих хэрэгтэй болно.

Declare операторын тайлбар нь маш их зай эзэлдэг бөгөөд кодын цонхны ойролцоо нэг мөрөнд багтахгүй. Тиймээс бид програм бичихдээ ямар ч төрлийн мөр дамжуулах схемд анхаарлаа хандуулахыг зөвлөж байна, жишээлбэл:

Функцийг зарлах GetTempPath _ Lib “kernel32” Alias​​“GetTempPathA” _ (ByVal nBufferLength As Long, _ ByVal lpBuffer String)

Энд янз бүрийн эгнээний тайлбарын бүх үндсэн элементүүдийг тайлбарласан бөгөөд уншихад таатай байна.

2. DLL функцтэй ажиллахдаа онцгой хүндэтгэлтэй хандана уу

Win API болон янз бүрийн DLL функцуудыг ашиглах нь VB-ийн функциональ чадавхийг ихээхэн өргөжүүлж, ихэнхдээ програмын бүтээмжийг нэмэгдүүлэх боломжийг олгодог. Гэсэн хэдий ч, үнийг төлөх үнэ нь роботын программуудын найдвартай байдал, ялангуяа хөгжүүлэлтийн явцад буурдаг.

VB дунд програмын хамгийн чухал давуу талуудын нэг нь програм боловсруулах үйл явцын найдвартай байдал юм: орчуулагчийн хүрээнд ажилладаг програмын код нь Windows болон VB роботыг эвдэх онолын хувьд боломжгүй юм. Програмист нь дуудаж буй функцэд параметрүүдийг зөв дамжуулах талаар тийм ч болгоомжтой хандахгүй байж магадгүй - ийм алдааг орчуулагч өөрөө кодыг орчуулах явцад эсвэл түүнийг гүйцэтгэх явцад амархан илрүүлдэг. Хамгийн муу тохиолдолд боловсруулалтын горимд утга учир, хаана, юу тохиолдсон талаар аль алинд нь тасалдал гарах болно.

Windows API эсвэл бусад DLL сангуудын шууд функцуудыг ашиглах нь өгөгдөл дамжуулах, VB дундаас гадуур код руу холбох үйл явцыг хянах боломжийг олгодог. Тиймээс гадаад функцүүдийн эвдрэл нь VB болон үйлдлийн системийн аль алиных нь эвдрэлд хүргэж болзошгүй юм. Хэрэв ашиг тус нь байгалийн жам ёсны юм бол энэ нь хөтөлбөр боловсруулах үе шатанд онцгой ач холбогдолтой юм. Тиймээс үндсэн системийн өргөн хүрээний функцээс шалтгаалан програмист нь тэдгээрийн хэрэгжилтийн зөв байдлыг хариуцдаг.

Процедурын хооронд параметр дамжуулах өөр өөр программууд өөр өөр байдаг тул асуудал улам төвөгтэй болж байна. (Илүү нарийвчлалтай хэлэхэд, бидний олонхи нь хэд хэдэн аргыг дэмжиж чаддаг тул дамжуулах янз бүрийн аргуудыг хэлэлцэх болно.) Win API нь C/C++ хэл дээр хэрэгжсэн бөгөөд бид энэ системд хүлээн зөвшөөрөгдсөн Are excluded гэх мэт параметрүүдийг дамжуулах талаар ярих хэрэгтэй. стандарт VB сонголтоос.

Үүнтэй холбогдуулан API функцүүдийн VB аналоги гарч ирэх нь үлдсэнийг нь VB синтакс руу дасан зохицож, өгөгдөл солилцоог хянах ижил төстэй механизмыг хэрэгжүүлснээр зөвтгөгдөж байгааг тэмдэглэх нь зүйтэй. Хөтөлбөрийн эцсийн боловсруулалтын үе шатанд хөрвүүлсэн модулийг бүтээхдээ Native Code (машины код) биш харин P-код эмхэтгэх сонголтыг сонгох нь дээр гэдгийг бид талархаж байна. Эхлээд програм нь орчуулагчийн хяналтан дор ажилладаг - машины кодыг ашиглахаас илүүтэйгээр үйлдлийн системийг харж, боломжит алдааг тодорхойлох гарын авлагын горимыг хангасан нь дээр.

Porada 3. VB дээр найдвартай API програмчлалын талаар Дан Эпплманаас өгсөн арван зөвлөмж

API-ийн янз бүрийн функцууд нь процедурыг томруулах энгийн бус аргуудыг ашиглан илүү нарийн програмчлал шаарддаг (VB-тэй харьцуулахад). Ирээдүйд бид энэ хоолноос бага багаар өлсөж байна. Одоо бид Дэн Эпплмэний энэ сэдвээр хийсэн хэлэлцүүлгийн хураангуйг (эхний хувилбар нь 1993 онд гарсан) зарим нэмэлт тайлбарын хамт танилцуулах болно.

1. ByVal-ийн талаар санаарай.Функцүүдийн өмнө API болон DLL-г хэрэгжүүлэхэд тохиолддог хамгийн нийтлэг асуудал бол ByVal түлхүүр үгийн буруу толь бичигт байдаг: тэд үүнийг оруулахаа мартдаг, эсвэл эцэст нь шаардлагагүй үед тавьдаг.

Эдгээр жишээнүүд нь параметрүүдийг шилжүүлэхийн тулд ByVal операторын оролтыг харуулж байна

Параметрийн төрөл Z ByVal ByVal-гүй
Бүхэл тоо Стек нь 16 битийн багтаамжтай Стек нь 16 битийн бүхэл тооны 32 битийн хаягийг багтаах боломжтой
Урт Стек нь 32 битийн багтаамжтай Стек нь 32 битийн бүхэл тооны 32 битийн хаягийг багтаах боломжтой
Мөр Дараалал нь C хэлэнд хэрэглэгддэг формат руу хөрвүүлэгддэг (хойд талын хоосон байтыг өгсөн). Шинэ эгнээний 32 битийн хаягуудыг стек дээр байрлуулсан Стек нь мөрийн VB тодорхойлогчийг агуулна. (Ийм тодорхойлогчийг Windows API өөрөө хэзээ ч танихгүй бөгөөд зөвхөн VB-д зориулагдсан DLL-д танигдана.)

VB гэх мэт аливаа програмчлалын систем дэх параметрийн дамжуулалтыг илгээх (ByRef) эсвэл утга (ByVal) гэсэн хоёр үндсэн алхамаар тодорхойлдог гэдгийг энд дурдах нь зүйтэй. Эхний сонголт нь солилцооны хаягийг хүлээн авдаг (энэ сонголтыг VB-д солилцоход ашигладаг), нөгөө нь түүний утгыг хүлээн авдаг. Хүчин төгөлдөр байх зарчим нь нэмэлт мессежийн дараа залгаж буй програмыг дамжуулсан параметрийн өөрчлөгдсөн утга руу буцаах явдал юм.

Эхлэхийн тулд дараах програмуудыг ашиглан туршилт явуулна уу.

Dim v Бүхэл тоогоор v = 2 MyProc(v) MsgBox "v = " & v Sub MyProc (v Бүхэл тоогоор) v = v + 1 End Sub-г дуудах

Энэ програмыг ажиллуулсны дараа та хувьсагчийн утгын 3-тай тэнцүү мэдээллийг харах болно. Баруун талд, энэ тохиолдолд товшилтоор програмаар үүсгэгдсэн v хувьсагчийн хаягууд MyProc дэд програм руу шилждэг. . Одоо процедурын тайлбарыг өөрчил

Sub MyProc (ByVal v бүхэл тоогоор)

Үүний үр дүнд, та тестийг ажиллуулахдаа v = 2-ыг устгадаг бөгөөд энэ нь хувьсагчийн гаралтын утгыг процедурт дамжуулдаг гэсэн үг юм - үүн дээр ажиллаж байгаа үйлдлүүдийн үр дүн нь дууддаг програм руу буцаж ирэхгүй. Дуудлагын операторын тусламжтайгаар утгыг дамжуулах горимыг дараах байдлаар өөрчилж болно.

Sub MyProc (v As Integer) ... MyProc ((v)) '(v) дуудах - гарууд нь утгуудын ард _ дамжуулах горимыг заана.

Гэсэн хэдий ч, дотоод VB-процедурууд руу тэлэх үед Дуудлага мэдэгдэлд ByVal түлхүүр үгийг ашиглахыг хориглодог - үүний оронд дугуй гарыг хаадаг. Энд тайлбар байна.

Сонгодог хувилбарт (C, Fortran, Pascal) ByRef болон ByVal горимуудын ач холбогдол нь өгөгдөл солилцох стек дээр юу байрлуулсан - солилцооны хаяг эсвэл утгуудаас хамаарна. Basic-д програм хангамжийн эмуляцийн ByVal хувилбарыг түүхэнд ашиглаж ирсэн - цаг хугацааны өөрчлөлт үүсгэсэн утгыг дамжуулахаас бусад тохиолдолд стек нь үргэлж хаягуудыг агуулдаг. Хоёр сонголтыг (Сонгодог ба Үндсэн) хооронд нь ялгахын тулд ByVal горимыг тайлбарлах янз бүрийн арга байдаг. VB-д ByVal горимыг эмуляци хийх нь програмын найдвартай байдлыг хангах нь чухал юм: хөрвүүлэх хэлбэрийг хольж, програм нь өөрчлөлтийн утгыг засах замаар товшиж буй програмыг эргүүлэх (эсвэл эргүүлэхгүй) алдах эрсдэлтэй. . "Сонгодог" хувилбарт ийм төөрөгдөл нь эцсийн боловсруулалт хийснээс хойш нэг цагийн дотор үхэлд хүргэж болзошгүй юм (жишээлбэл, використын санах ойн хаягийн оронд өөрчлөгддөг, тэгтэй тэнцүү утгууд байдаг бол). ).

DLL функцууд нь "сонгодог" зарчмуудын дагуу хэрэгждэг тул аргумент бүрд өгөгдөл хэрхэн солилцох талаар тодорхой тайлбар шаарддаг. Энэ нь өөрөө Declare тайлбараар (илүү нарийвчлалтай, дамжуулсан аргументуудын жагсаалт) дамжуулан зарлах функц болж чадна. Ихэнх тохиолдолд Windows API функц эсвэл DLL-д параметрүүдийг дамжуулахыг ByVal түлхүүр үг ашиглан зааж өгдөг. Түүнчлэн, үүнийг Declare оператор дээр эсвэл функцийг дуудах үед шууд зааж өгч болно.

Буруу параметр дамжуулах өвийг шилжүүлэхэд хялбар байдаг. Хэрэв та хүчингүй хаяг сонговол GPF (General Protection Fault) мэдэгдлийг харах болно. Функц нь хүчинтэй хаягаас зайлсхийсэн утгуудыг татаж авдаг тул API функц нь гадаад талбарт (жишээлбэл, Windows цөмд) орж, бүх төрлийн гамшгийн үр дагаварт хүргэдэг.

2. Дамжуулж буй параметрийн төрлийг өөрчлөх.Үүнтэй адил чухал зүйл бол дамжуулагдсан параметрүүдийн зөв тоо, төрөл юм. Зарлах хэсэгт зарласан аргументууд нь API функцийн параметрүүдтэй тохирч байх шаардлагатай. Параметр дамжуулахтай холбоотой хамгийн том асуудал бол NULL ба тэгийн эгнээний хоорондох зөрүүтэй холбоотой байдаг - санах ойн ул мөр нь нэг юм.

3. Эргүүлж буй утгын төрлийг шалгана уу.

VB нь функцээр эргэлддэг утгын төрлүүдийн олон янз байдлыг тохируулахыг тэсвэрлэдэг бөгөөд зарим тоон утгыг стекээр биш харин регистрээр эргүүлдэг. Дараах дүрмүүд нь API функцээр буцаж ирсэн зөв утгыг тодорхойлоход тусална.

  • Утгыг эргүүлдэггүй DLL функц ('C'-д хүчингүй болсонтой адил) нь VB Sub-тай адил дүлий байж болно.
  • Утгыг эргүүлдэг API функцийг (бүхэл тоо эсвэл урт) дэд эсвэл тодорхой төрлийн утгуудыг эргүүлдэг функц гэж тодорхойлж болно.
  • Энэ API функц нь хөвөгч цэгийн тоог эргүүлдэггүй, гэхдээ DLL нь ийм төрлийн өгөгдлийг эргүүлж чаддаг.

4. Ямар ч төрлийн хийцийг маш болгоомжтой ашиглаарай. Windows API-ийн олон функцууд нь өөр өөр төрлийн параметрүүдийг хүлээн авч, As Any бүтэц дээр үндэслэн ашиглах чадвартай байдаг (төрлийн тайлбар нь дамжуулагдсан бусад параметрүүдийн утгаас хамаарна).

Сайн шийдлүүд нь ижил функцийг хуваалцдаг хоёр ба түүнээс дээш тооны хооронд олон нэрийн (Alias) функцтэй байж болох ба дуулах төрөл бүрийн тайлбарт параметрүүдийг зааж өгсөн болно.

5. Мөрүүдийг эхлүүлэхээ бүү мартаарай. Win API нь параметр болгон дамжуулсан мөрийн буферээс өгөгдлийг цуглуулах замаар мэдээллийг эргүүлэх энгийн функцтэй. Програмдаа та бүх зүйлийг зөв хийж чадна: ByVal-ийн талаар бүү мартаарай, параметрүүдийг функцэд зөв шилжүүлээрэй. Гэсэн хэдий ч Windows нь санах ойн хэмжээ хэр том болохыг харж чадахгүй байна. Мөрний хэмжээ нь түүнд байрлуулж болох бүх өгөгдлийг багтаахад хангалттай байх ёстой. Шаардлагатай хэмжээтэй буфер нөөцлөх үүрэг нь VB программист хамаарна.

Өөр өөр мөр бүхий 32 битийн Windows үйлдлийн системд үндэсний системийн тохиргооноос хамааран Юникод (хос байт кодчилол)-оос ANSI (нэг байт кодчилол) руу хөрвүүлэх боломжтойг анхаарна уу. Тиймээс буферийг нөөцлөхийн тулд ердийнхөөс илүү байт массив ашиглах нь илүү аюулгүй байдаг. (Энэ тухай тайланг доор хэлэлцэх болно.)

Ихэнх Win API функцууд нь блокийн хамгийн дээд хэмжээг өөрөө тохируулах боломжийг олгодог. Жишээлбэл, та блокийн хэмжээг зааж өгөх өөр API функцийг дуудах хэрэгтэй. Жишээлбэл, GetWindowTextLength нь GetWindowText функцэд агуулагдах цонхны гарчгийг байрлуулахад шаардагдах мөрийн хэмжээг тодорхойлох боломжийг олгодог. Энэ шалтгааны улмаас Windows таныг хилээс цааш явахгүй гэдгийг баталгаажуулдаг.

6. Vikorize Option Explicit хоёр хэл дээр.

7. Параметрүүдийн утгууд болон эргүүлж буй утгуудыг сайтар шалгана уу. VB нь төрлийг шалгах боломжтой. Энэ нь хэрэв та VB функцэд буруу параметр дамжуулахыг оролдвол хамгийн муу зүйл бол VB-ийн алдааны мэдэгдлийг үгүйсгэх явдал юм. Харамсалтай нь, энэ механизм нь Windows API функц руу шинэчлэгдсэн үед ажиллахгүй.

Windows 9x нь ихэнх API функцүүдийн параметрүүдийг шалгах боловсронгуй системтэй. Тиймээс эдгээр өгөгдөлд өршөөл үзүүлэх нь үхлийн нөхөн төлбөр гэсэн үг биш боловч юунаас болж үүссэнийг тодорхойлох нь тийм ч хялбар биш юм.

Энэ төрлийн сүүг сайжруулах хэд хэдэн аргыг эндээс олж болно.

  • API функцийн арьсны хариуг шалгахын тулд арьсны горим эсвэл Debug.Print-г шалгана уу. Бүх зүйл хэвийн хэмжээнд байгаа, функц зөв хийгдсэн эсэхийг шалгахын тулд эдгээр товшилтуудын үр дүнг хянана;
  • Vikorist бол CodeView болон Windows-ийн тохируулсан хувилбар (Windows SDK-ээс) зэрэг Windows-д суурилсан хөгжүүлэгч юм. Эдгээр функцууд нь параметрийн өөрчлөлтийг илрүүлж, хамгийн чухал нь аль API функцийг өөрчлөхийг тодорхойлох боломжтой;
  • Гуравдагч талын компаниудын нэмэлт шинж чанаруудыг шалгаж, параметрийн төрлүүд, тэдгээрийн утгыг хүлээн зөвшөөрөх боломжтой эсэхийг шалгана уу. Ийм аргууд нь параметрийн өөрчлөлтийг олохоос гадна VB кодыг хаана өөрчлөлт хийснийг хэлж чаддаг.

Үүнээс гадна API функцийн үр дүнг сайтар шалгаж үзэх шаардлагатай.

8. VB болон Windows дээрх тоонууд ижил биш гэдгийг санаарай. VB хэл дээрх "бүхэл тоо" гэсэн нэр томъёо нь 16 битийн тоог илэрхийлдэг бол Win 32 баримт бичигт 32 битийн тоог илэрхийлдэг гэдгийг эхлээд санацгаая. Өөрөөр хэлбэл, VB дахь бүхэл тоонууд (Бүхэл ба Урт) нь тэмдэггүй утгууд биш (нэг цифрийг тэмдэг болгон, нөгөөг нь тооны мантис болгон ашигладаг), Windows дээр үл мэдэгдэх тоонуудыг ч ашигладаг. Хэрэв та нэмэлт арифметик үйлдлүүд ашиглан параметр үүсгэвэл (жишээлбэл, суурь ба офсетийн нэмэлт орлуулалт ашиглан хаягийг тооцоолох) энэ нөхцөл байдлыг харгалзан үзэх шаардлагатай. Аль стандарт VB арифметик функцууд тохирохгүй байна. Та яагаад ийм байдлаас айгаад байгаа юм бэ, энэ талаар ярилцъя.

9. Функцийн нэрэнд болгоомжтой ханд. Win16-д Win32 API-ийн бүх функцуудын нэр нь жижиг болон том үсгүүдийн яг өөрчлөлтөд мэдрэмтгий байдаг (Win16-д ийм зүйл байгаагүй). Хэрэв та агуу зохиолчийн оронд жижиг зохиолчийг тавьж байгаа бол шаардлагатай функц олдохгүй. Мөрийн параметрүүдийг тохируулахын тулд функцүүдийн зөв дагавар A эсвэл W дагаарай. (Энэ талаар мэдээлнэ үү - div. доор.)

10. Ажлынхаа үр дүнг аль болох олон удаа хадгал.Буруу DLL болон Win API скриптүүдтэй холбоотой алдаанууд нь VB дундын програм хангамж, магадгүй бүх үйлдлийн системийг сүйрүүлэхэд хүргэдэг. Туршилтын өмнө таны кодыг хадгалахад анхаарна уу. Хамгийн энгийн зүйл бол VB орчинд төслийг эхлүүлэхийн өмнө төсөлд модулиудыг автоматаар бичих горимыг тохируулах явдал юм.

Өмнөхийг уншсаны дараа Win API функцийг баруун талаас хассан нь таныг гайхшруулж магадгүй юм. Дашрамд хэлэхэд, энэ нь үнэн, гэхдээ зөвхөн VB өөрөө өгдөг аюулгүй програмчлалын дагуу. Гэсэн хэдий ч бага зэргийн зогсонги байдал, мэдэгдэж болзошгүй бэрхшээлүүдийн хувьд энэ эрсдэл хамгийн бага байдаг. Нэмж дурдахад Win API-ийн зогсонги байдлыг даван туулах нь ихэвчлэн боломжгүй байдаг - энэ нь ноцтой хөгжсөн тохиолдолд шаардлагатай хэвээр байх болно.

Үүнээс өмнө бид DLL-ийн өргөн ангиллын "усан доорх" чулуунуудын талаар өмнө нь бодож байсан. Win API-ийн тусламжтайгаар бүх зүйл илүү хялбар байдаг, учир нь эдгээр функцийг хэрэгжүүлэх хэлбэр нь тодорхой нэгдмэл байдаг. Ээжийн хүндэтгэлийг анхаарч үзэх ёстой гол зүйлүүд энд байна.

  1. Win32 API-ийн функцууд нь функцууд эсвэл Функцийн төрлийн процедурууд юм (Win16 API нь олон дэд програмтай байсан). Бүх функцууд нь Long төрлийнх тул тэдгээрийн тайлбарыг дараах хэлбэрээр бичнэ: Функцийн нэрийг зарлах ... Урт ‘ функцийн төрөл _ тодорхой хэлбэрээр бичигдсэн тул

    Declare Function name& 'function type _-г нэмэлт дагавараар тэмдэглэнэ

    API функц руу хөрвүүлэх нь дараах байдалтай байна.

Үр дүн& = ApiName& ([ Аргументуудын жагсаалт]
  1. Эргүүлсэн хамгийн чухал функц бол үйл ажиллагааг дуусгах код юм. Түүгээр ч зогсохгүй тэг утга нь хэвийн гүйцэтгэлийг илэрхийлдэг бол тэг утга нь гүйцэтгэлийг илэрхийлдэг. Дахин нэг удаа (эсвэл өмнө нь биш) та GetLastError функцийг ашиглан нэмэлт өөрчлөлтийн мөн чанарыг тодруулж болно. Энэ функцийн тайлбар дараах байдалтай байна: GetLastError & Lib функцийг зарлах "kernel32" ()

    UVAGA! VB-ийн дунд ажиллахдаа боловсронгуй кодын утгыг арилгахын тулд LastDLLError Err объектыг ашиглах нь дээр, учир нь VB нь API-ийн шинэчлэлт болон програмыг үргэлжлүүлэн ажиллуулах хооронд GetLastError функцийг дахин тохируулдаг.

    Та GelLastError үүсгэдэг кодыг API32.TXT файлд бичсэн нэмэлт тогтмолуудыг ашиглан ERROR_ дагавараар эхэлсэн нэрээр тайлбарлаж болно.

    Хамгийн түгээмэл халдлагын төрлүүд нь дараах кодууд юм.

    • ERROR_INVALID_HANDLE = 6& - буруу бариул
    • ERROR_CALL_NOT_IMPLEMENTED = 120& - зөвхөн Windows NT дээр ашиглах боломжтой Windows 9x функцуудыг дуудах
    • ERROR_INVALID_PARAMETER = 87& - параметрийн утга буруу

    Гэсэн хэдий ч өгөгдсөн параметрийн утгыг эргүүлэх олон функц байдаг (жишээлбэл, OpenFile нь файлын тайлбарын утгыг эргүүлдэг). Энэ тохиолдолд утгыг бусад тусгай Return& утгуудад оноодог бөгөөд ихэнхдээ 0 -1 байдаг.

  2. Win32 API нь хамгийн энгийн төрлийн өгөгдлийг дамжуулах хатуу аргуудтай. a) ByVal...As Long

    Аргумент дамжуулалтын дор хаяж 80% нь Long төрлөөр хийгддэг. Аргументыг эргэн харах юуны өмнө ByVal түлхүүр үг дагалддаг бөгөөд энэ нь бусад зүйлсээс гадна VB програмаас API функц хүртэл нэг талын өгөгдөл дамжуулах холбогдсон гэсэн үг юм.

    B) ByVal...Мөр хэлбэрээр

    Энэ төрлийн дамжуулалт нь байнга тохиолддог бөгөөд ижил аргументтай байдаг юуны өмнө ByVal гацсан. API функцийг дуудах үед мөрийн хаягуудыг стек рүү бичиж, хоёр талын өгөгдөл солилцох боломжийг олгодог. Эгнээгээр ажиллахдаа зарим асуудлуудыг анхаарч үзэх хэрэгтэй.

    Нэгдүгээрт, мөрийн санах ойн захиалга нь дууддаг програмаар хийгддэг тул API функц нь мөрүүдийг хадгалах юм бол дуудахаасаа өмнө шаардлагатай хэмжээтэй мөр үүсгэх шаардлагатай. Жишээлбэл, GetWindowsDirectory функц нь 144 тэмдэгтээс илүүгүй Windows лавлах замыг эргүүлдэг. Мэдээжийн хэрэг, энэ функцийг хэрэгжүүлэх нь иймэрхүү харагдах болно:

    WinPath$ = Space$(144) ' _ 144 тэмдэгтийн мөрийг нөөцөлж байна Үр дүн& = GetWindowsDirectory& (WinTath$, 144) _ ' буфер дүүргэлт ' Үр дүн& - нэрний тэмдэгтийн бодит тоо _ директорийн WinPath$ = Left$(WinPath, Үр дүн&)

    Өөр нэг асуудал бол API функцийг API функц болгон хөрвүүлэх үед гаралтын мөр нь дотоод дэлгэц дээр дахин бүтээгддэг бөгөөд функцээс гарах үед ижил аргаар үүсдэг. Win16-ийн эхний өдрүүдэд энэ үйлдэлд зөвхөн тэг байт, жишээ нь мөр нэмэх шаардлагатай байсан шиг Win32 гарч ирснээр Юникод хоёр байт кодчилолыг ANSI болгон хувиргасан гэх мэт. . (Энэ тухай "VB дахь эгнээний өөрчлөлт бүхий роботуудын онцлог" нийтлэлд, Computer Press 10'99 ба 01'2000-д мэдээлсэн болно). ByVal-ийн тусламжтайгаар ... String building-ийн хувьд тэмдэгт өгөгдлийн мөрүүдийг солилцох боломжтой болсон нь маш чухал юм.

    B) ...Ямар ч байсан

    Энэ нь санах ойн буфер хаягийн утгыг стек дээр байрлуулна гэсэн үг бөгөөд жишээ нь API функц юу зохицуулахын оронд тайлбар нь бусад аргументуудын утгаас үл хамаарна. Гэсэн хэдий ч As Any-г зөвхөн Declare операторт ашиглах боломжтой - тодорхой функцийг ашиглах үед аргументыг тодорхой утгыг оноож болно.

    D) ... UserDefinedType байдлаар

    Ийм бүтэц нь бусад бүтцийн төлөө мэдээлэл солилцох (зөрчил гаргасан талын амлалт) шаардлагатай үед ихэвчлэн гацдаг. Үнэн хэрэгтээ энэ загвар нь As Any дамжуулалтын маягтыг хэрэгжүүлэх энгийн хэлбэр бөгөөд функц бүр нь тогтсон бүтэцтэй байдаг.

    Өгөгдлийн бүтцийн хэлбэр нь тодорхой API функцээр тодорхойлогддог бөгөөд тэдгээрийг ижил програмаар зөв тодорхойлж, нөөцлөх нь програмын үүрэг юм. Энэ бол дизайн юуны өмнөвикорист гүйгээр ByVal гэсэн үгс, дараа нь илгээсний дараа шилжүүлгийг энэ хайрцагт нэмнэ - солилцооны хаягийг стек дээр бичнэ.

API функц хүртэл өгзөг

Үүнийг дараах байдлаар тайлбарласан файлуудтай ажиллах үндсэн хоёр функц болох lopen болон lread-ын жишээн дээр харуулав.

Функцийг lopen Lib "kernel32" _ Alias ​​"_lopen" (_ ByVal lpFileName String, _ ByVal wReadWrite As Long) гэж зарлах функцийг lread Lib "kernel32" _ Alias ​​"_lread" (_ ByVal hFile As Long, lpBuff _ ByVal wBytes As Long) As Long

VB-д тэдгээрийн аналогууд нь заримдаа илүү нарийвчлалтай байдаг - Open and Get операторууд (хоёртын горимд зориулагдсан). Хоосон функцэд Alias ​​түлхүүр үгийг ашигласан нь бидэнд маш их сэтгэгдэл төрүүлсэн - хэрэв та үүнгүйгээр хийж чадахгүй бол энэ нь яг адилхан асуудал юм. Номын сангийн эдгээр функцийн нэрүүд нь VB-д зөвшөөрөгдөөгүй сандал доорх тэмдэг (C киноны ердийн хэв маяг) тэмдэгээр эхэлдэг.

Файл нээх ажиллагаа дараах байдалтай байж болно.

Const INVALID_HANDLE_VALUE = -1 ' хүчингүй _ утгын тайлбар lpFileName$ = “D:\calc.bas” ' файлын нэр wReadWrite& = 2 ' унших-бичих горим hFile& = lope(lpFileName$, wReadWrite&) _ IN_AL_H = Дараа нь V_AL_V'd файлыг засах ' засах кодыг зааж өгөх CodeError& = Err.LastDllError 'CodeError& = GetLastDllError _ ' энэ бүтэц ажиллахгүй байна.

Энд бид хоёр зүйлийг онцлон тэмдэглэх ёстой.

  • Функцийн утгын хувьд бид файлын тайлбарын утгыг тодорхойлно. Утга нь -1 утгыг баталгаажуулна;
  • Энэ тохиолдолд GetLastError функц руу орох шаардлагагүй - алдааны заасан утгыг олж авахын тулд бид Err объект руу очсон (бид ийм нөхцөл байдал үүсэх боломжийн талаар илүү их ярьсан).

Дараа нь та файлын оронд уншиж болно, гэхдээ энэ нь програм нь түүний бүтцийг таних үүрэгтэй гэдгийг илтгэнэ (олон давхар файлтай ажиллахад тохиолддог шиг). Энэ тохиолдолд lread функцийг хэрэгжүүлэх нь дараах байдлаар харагдаж болно.

Dim MyVar As Single wBytes = lread (hFile&, MyVar, Len(MyVar) ' ярианы дугаарыг унших, 4 байт ' wBytes - бодитоор уншсан өгөгдлийн тоо, '-1 - parity... MyStruct x Single i-г бүхэл тоогоор бичнэ үү. Төгсгөлийн төрөл Dim MyVar MyStruct байдлаар wBytes = lread (hFile&, MyVar, Len(MyVar)) ' унших өгөгдлийн бүтэц, 6 байт

Дахин нэг удаа хүндэтгэл үзүүлээрэй: функцийн нөгөө аргумент нь илгээгчид болон утгууд руу буцах явдал юм.

MyVar As String MyVar = Space$(10) ' 10 тэмдэгтийн зайг нөөцлөөрэй wBytes = lread (hFile&, ByVal MyVar, Len(MyVar)) ' унших тэмдэгтийн мөр, 10 тэмдэгт

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

Массив дахь файлын оронд уншихыг (хялбар болгохын тулд бид нэг байт массив ашиглана) дараах байдлаар эмхэтгэсэн:

Dim MyArray(1 to 10) As Byte wBytes = lread (hFile&, MyArray(1), _ Len(MyArray(1))* 10) ‘ массиваас 10 элемент уншина

Массивын эхний элементийг аргумент болгон зааж өгснөөр бид массивын хувьд нөөцлөгдсөн санах ойн хэсгийн толгойн хаягийг дамжуулдаг. Мэдээжийн хэрэг, та энэ аргыг ашиглан массивын дурын фрагментийг хадгалах боломжтой:

WBytes = lread (hFile&, MyArray(4), _ Len(MyArray(1))* 5) 4-8-р массивын элементүүдийг унших

Порада 5. Шилжүүлэхэд зориулсан Викорий нэрТохиргоог дурын адил

Энд, урд өгзөг дээр үндэслэн бид Дэн Appleman-ийн төлөө дөрөв дэх мөн чанарыг илчилдэг.

lread функцтэй ажиллахдаа түүний өмнө энгийн хувьсагчийг ажиллуулахдаа ByVal түлхүүр үгийг ашиглах шаардлагатай гэдгийг санах нь чухал (эсвэл хууль бус үйлдлийн талаарх мэдээлэл алга болохгүй). Аюулгүй байхын тулд та зөвхөн нийтлэг өөрчлөлтүүдтэй ажиллахын тулд энэ функцийн нэмэлт тусгай тайлбарыг үүсгэж болно:

lreadString Lib "kernel32" _ Alias ​​​​"_lread" (_ ByVal hFile As Long, ByVal lpBuffer String, _ ByVal wBytes As Long) функцийг зарлах

Энэ тайлбартай ажиллахдаа хэвлэхдээ ByVal-ийг зааж өгөх шаардлагагүй болно.

WBytes = lreadString(hFile&, MyVarString, _ Len(MyVarString)) ‘

Declare операторын синтакс нь массивын хувьд ийм тусгай тайлбар үүсгэх боломжийг олгодог бололтой.

lreadString Lib "kernel32" функцийг "_lread" (_ ByVal hFile As Long, lpBuffer() Byte, _ ByVal wBytes As Long) гэж зарлах

Хамгаалах амьтан

WBytes = lreadArray(hFile&, MyArray(), 10)

хөтөлбөрөөр үхэлд хүргэх нь гарцаагүй.

Энэ бол Visual Basic-ийн мөрийн өөрчлөлтийг боловсруулах онцлогийн талаархи хэлэлцүүлгийн үргэлжлэл юм: VB нь хоёр байт Unicode кодчилол, Win API - нэг байт ANSI (мөн C хэлээр хүлээн зөвшөөрөгдсөн форматтай - төгсгөлд нь тэг байт) ашигладаг. Мөрийн өөрчлөлтийг аргумент болгон өөрчлөх үед API функцийг (илүү нарийвчлалтай, DLL функц) дуудах үед Юникодоос ANSI руу хөрвүүлэх нь автоматаар хийгдэх бөгөөд эргүүлэх үед хувиргах нь тодорхой байна.

Энд гол санаа нь энгийн: та хувьсагчийн тусламжтайгаар симбол өгөгдлийг солилцож болно, гэхдээ тэдгээрийг хангалттай давхар мэдээлэл солилцоход ашиглах боломжгүй (VB-ийн 16 битийн хувилбаруудтай ажиллахад ашигладаг байсан). Нэг хэмжээст байт массив ашиглах нь дээр.

String төрлийг бүтцийн бүтцийг тодорхойлоход ашиглаж болох бололтой. Энэ санах ойтой холболт дараах байдалтай байна.

  • Win API-г хөгжүүлэхэд дараах бүтцийг ашиглах боломжгүй юм: MyStruct x As Single s As String гэж бичнэ үү.

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

  • Энэ нь тогтмол давхарлалтын эгнээний бүтцийн элемент болох боломжтой: MyStruct x As Single s As String*8 ‘ гэж бичнэ үү. Тогтмол давхардлын эгнээ Төгсгөлийн төрөл

Энэ тохиолдолд кодыг дахин үүсгэхээ мартуузай.

Мөн хүндэтгэл хэвээр байна: API функцийг нэгэн зэрэг шинэчлэх үед эгнээний олон тооны өөрчлөлтийг (тогтмол болон өөрчлөгдөх боломжтой) нэгтгэх боломжгүй юм. Тэгэхгүй бол “хууль бус ажиллагаа” гарах нь баталгаатай болно.

Хэрэв та номын сандаа DLL функц бичих шаардлагатай бол та муу нөхцөл байдалд байгаа нь тодорхой байна. Хэрэв та холимог програмчлалын технологи - нэг хөтөлбөрийг хэрэгжүүлэхийн тулд хоёр ба түүнээс дээш програмыг хослуулан хэрэглэвэл хэрэгцээ гарах нь гарцаагүй.

Холимог программчлал нь иж бүрэн тайланд хүрэхийн тулд хэрэгжүүлэх үндсэн зорилт болж байгаатай холбогдуулан ач холбогдолтой юм. Үнэн хэрэгтээ хэлний хэл (илүү нарийвчлалтай хэл дээр суурилсан програмчлалын систем) нь өөрийн давуу болон сул талуудтай тул янз бүрийн даалгавруудыг биелүүлэхийн тулд янз бүрийн хэрэгслийн давуу талыг ашиглах нь бүхэлдээ логик юм. Жишээлбэл, VB - компьютерийн интерфейс үүсгэх, C - системийн нөөцөд үр дүнтэй нэвтрэх, Fortran - тоон алгоритмуудыг хэрэгжүүлэх.

Зохиогчийн санаа нь энэ юм: програмчлалд нухацтай оролцохыг хөгжүүлэгч хоёр хэрэгслийг ашиглан онцолдог. Мэдээжийн хэрэг, орчин үеийн оюун ухаанд хоёр системийн бие даасан шинжээч байх нь маш хэцүү бөгөөд энэ нь "үндсэн ба нэмэлт хэл" схемийг илүү логик болгодог. Энд байгаа санаа бол "нэмэлт" хэлний мэдлэгийг (хэд хэдэн энгийн журмын дагуу бичсэн) авчрах нь "үндсэн" хэлний үр нөлөөг мэдэгдэхүйц нэмэгдүүлэх болно. VB-ийн мэдлэг нь нэмэлт давуу тал болох нь одоо мэргэжлийн програмистын практик шаардлага болсон нь чухал юм. Ярихаасаа өмнө DOS-ийн хэдхэн цагийн дотор ямар ч програмист Basic-ийг харцгаая, Ассемблерийн үндсийг мэдэх нь туйлын чухал байх болно.

Тиймээс энэ нь өөр, гэхдээ бүлгийн роботуудын оюун ухаанд арьсны програмист өөрийн гэсэн тусгай ажил эрхэлдэг бол янз бүрийн хэл дээрх процедурын интерфейсийн онцлог шинж чанаруудын талаархи мэдэгдэл нь төслийн бүх оролцогчдын буруу юм. Интерфэйсээс гадна өөр аргуудыг тохируулах, програмчлалын аргуудыг процедур болгон өргөжүүлэх, интерфэйсийг дасан зохицох боломжийг олгодог маш олон програмчлалын системүүд (VB орно) байдгийг би мэднэ. Бусад хэл.

Процедур хоорондын интерфэйсийг ашиглахдаа дараах боломжит бэрхшээлүүдийг анхаарч үзээрэй.

  • Тодорхойлогч бичих дүрмийн талаар өөр өөр хэлүүд танд сонирхолтой байж магадгүй юм. Жишээлбэл, VB-д нуугдаж буй процедурын нэрний алиас тэмдгийг ихэвчлэн ашигладаг. Энэ асуудлыг Declare оператор дахь Alias ​​түлхүүр үг ашиглан хялбархан тайлбарлаж болно (2.3-ийн маш сайн жишээ).
  • Та стек рүү дамжуулж буй аргументуудыг бичих дарааллыг тодорхойлж болно. Жишээлбэл, DOS цагийн дотор (үнэнийг хэлэхэд Windows-ийн дунд ямар байдгийг мэдэхгүй байна), жагсаалтын төгсгөлөөс аргументуудыг бичиж, бусад хэл дээр (Фортран, Паскаль, Basic) -аас. эхлэл.
  • Заавар эсвэл утгын хувьд параметрүүдийг шилжүүлэх янз бүрийн зарчмуудыг тайлбарласан болно.
  • Цогцолборыг хадгалах хатуу зарчим. Жишээ нь, С хэлэнд (Фортран, Паскаль хэл дээрхтэй адил) мөрийн төгсгөлийг төгсгөлд нь тэг байтаар заадаг бол Basic хэл дээр төгсгөлийг мөрийн тодорхойлогч дээр тодорхой бичсэн байдаг. Тэмдгийн янз бүрийн кодыг өөрчлөх чадварыг санах нь мэдээжийн хэрэг.
  • Баялаг ертөнцийн массивыг шилжүүлэхдээ баялаг ертөнцийн бүтцийг нэг ертөнц дээр өөрчлөх өөр өөр сонголтууд байдаг гэдгийг санаарай (эхний индексээс эсвэл сүүлчийн зуун хоёр хэмжээст массиваас - "мөр дотор" эсвэл "мөр дотор" дэгдээхэйнүүд").

Үүний үндсэн дээр дараахь зөвлөмжийг гаргаж болно.

  • Аргументуудыг DLL функц руу шилжүүлэх арга замыг засаж, хамгийн энгийн зүйлсийг шалгаарай. Win API-д батлагдсан стандартууд нь бүрэн нийцдэг.
  • Тэр болгонд жирийн цэргүүдийг бөөнөөр нь бүү шилжүүл.
  • Энгийн энгийн, баялаг массивыг шилжүүлэхэд хүндэтгэлтэйгээр vikorist.
  • Аргументуудыг дуудаж, буцааж байгаа процедурт дамжуулах механизмын ажиллагааг сайтар шалгаж үзээрэй. Өгөгдлийг баталгаажуулахын тулд тусгай тест бичнэ үү. Арьс аргументыг шилжүүлэх зөв эсэхийг сайтар шалгана уу. Жишээлбэл, хэрэв танд олон аргумент бүхий процедур байгаа бол эхлээд нэг аргументтай сонголтын арьсны параметрийг дамжуулж, дараа нь бүхэл бүтэн жагсаалтын зөв эсэхийг шалгана уу.

Жишээлбэл, Fortran дээр DLL функц аль хэдийн бичигдсэн боловч оролтын интерфейс нь шинэ VB стандарттай тохирохгүй байвал энэ нь юу хийх вэ? Энд та хоёр огноо өгч болно. Нэгдүгээрт: туршилтын DLL функцийг бичиж, түүний тусламжтайгаар VB програмуудад шаардлагатай функцийг сонгохын тулд туршилт, алдааны аргыг ашиглаж үзээрэй. Өөр нэг нь: агуулах дахь энгийн өгөгдлийн бүтцийг хувиргах (жишээлбэл, эгнээний массиваас том байт массивыг хувиргах) бүхий VB ба DLL функцийн хоорондох энгийн интерфейсийг хангах адаптерийн процедурыг Fortran дээр бичих.

Otzhe: vykorist DLL функцууд. Мөн чихэрлэг амтыг хадгалаарай.

ComputerPress 9"2000

Энэ нийтлэлийг C++ хэл дээр програмчлалд шинээр орж, WinAPI ашиглахаас өөр аргагүйд хүрсэн хүмүүст зориулав.
Би тоглолтын өмнө гарахыг хүсч байна:
Би өөрийгөө C++ эсвэл WinAPI багш гэж дүр эсгэдэггүй.
Би дөнгөж эхэлж байгаа бөгөөд WinAPI-ийн функц, механизмыг ашиглахад хялбар болгох хэд хэдэн програмуудыг энд танилцуулахыг хүсч байна.

Энэ нийтлэлд та анги үүсгэх, өөр өөр операторуудыг шилжүүлэх чадвартай байхын тулд C++ хэлийг аль хэдийн мэддэг болсон бөгөөд та өөрийн механизмуудыг анги руу "хайрласан" гэж би бодож байна.

Консолын бүтээл ба використан

Win32 программыг сайжруулахын тулд, эсвэл бүх зүйл дунд нь хэрхэн харагдаж байгааг гайхшруулахын тулд би үргэлж консолыг маажих болно.
Та консол гэхээсээ илүү GUI програм үүсгэж байгаа тул консол холбогдохгүй. Интернет дээр дарахын тулд та энэ кодыг олох боломжтой

Хэрэв(AllocConsole())
{



std ::ios :: stdio_тэй синхрончлох();
}
Тодорхой болгохын тулд Ража үүнийг функцэд оруулав. Жишээлбэл:
CreateConsole () хүчингүй
{
хэрэв (AllocConsole())
{
int hCrt = _open_osfhandle((урт)GetStdHandle(STD_OUTPUT_HANDLE), 4);
*stdout = *(::_fdopen(hCrt, "w"));
::setvbuf(stdout, NULL, _IONBF, 0);
*stderr = *(::_fdopen(hCrt, "w"));
::setvbuf(stderr, NULL, _IONBF, 0);
std ::ios :: stdio_тэй синхрончлох();
}

Консол нь зөвхөн дэлгэцийн горимд ажилладаг бөгөөд консолын програмуудтай ижил аргаар ажилладаг. Мэдээллийг өмнөх шигээ оруулна уу - cout/wcout.
Энэ кодыг үр дүнтэй болгохын тулд төсөлд дараах файлуудыг оруулах шаардлагатай.
#оруулна
#include #include
мөн глобал нэрийн талбарт std нэрийн орон зайг идэвхжүүлнэ:
namespace std ашиглах;
Мэдээжийн хэрэг, хэрэв та юу ч хийхийг хүсэхгүй байгаа бол std::-г дотор нь байгаа бүх зүйл дээр нэмнэ үү.

Харагдах объект болон арифмыг багасгах. үйл ажиллагаа

Та үүсгээд "эцэст нь" оруулсны дараа эхлээд консол руу ямар нэгэн утгыг гаргах ёстой.
Жишээлбэл:
Та GetClientRect нэмэлт функцийг ашиглан цонхны үйлчлүүлэгчийн талбайн хэмжээг тодорхойлдог бөгөөд энэ объектыг мэдээллээр дүүргэхийн тулд RECT бүтцийн объектын хаяг руу параметрийг дамжуулдаг. Хэрэв та баригдсан үйлчлүүлэгчийн талбайн хэмжээг мэдэх шаардлагатай бол аль хэдийн холбогдсон консол дээр үүнийг бичиж болно.

Коут<

Ale ажил маш хурдан (ялангуяа та ихэвчлэн ийм ажиллах шаардлагатай байдаг учраас) амар биш юм.
Энд л тайван байдал бидэнд туслах болно.
RECT бүтцээс нээлттэй задрах анги үүсгэж, гаралтын мэдэгдлийг дахин зориул<< так, как вам угодно.
Жишээлбэл:

Шинэ анги: нийтийн RECT
{
олон нийтэд:
найз ostream & оператор<<(ostream &strm,newrect &rect)
{
strm<<"Prtint RECT object:\n";
strm<буцах strm;
}
};

Одоо зүгээр л cout/wcout ашиглан объектыг бичнэ үү:

Коут<

Мөн бүх зүйл танд хэрэгтэй байгаагаар байгааг та өөрөө харж болно.
Мөн өөрт хэрэгтэй ямар ч оператортой ажиллах боломжтой.
Жишээлбэл, хэрэв та бүтцийг өөрчлөх эсвэл хуваарилах шаардлагатай бол (жишээлбэл, RECT эсвэл POINT) - оператор==() болон оператор=()-ыг бүрэн өөрчил.
Хэрэв та операторыг бага хэрэгжүүлэхийг хүсч байвал< что бы быстро сравнивать размеры окна и т.д. перегрузите operator<().
Тиймээс та ямар ч бүтэцтэй, тэр дундаа RECT бүтцийн үндсэн объекттой ажилладаг бүх функцүүд үүнтэй адилхан ажиллах болно гэж би бодож байна.
Би энэ бүх гоо сайхныг холбогдсон тусдаа файлд хийж, шаардлагатай бол засварлахыг зөвлөж байна.

Танай анги

Би бусдын талаар мэдэхгүй ч би бүрэн ногоон, арьсны функц эсвэл номын арьсны хэсэг/дэд хэсэгт зориулж шинэ төсөл зохиохоор шийдсэн бөгөөд ингэснээр бүх зүйл эмх цэгцтэй, хүссэн үедээ боломжтой болно. эргүүлж, дурсамжаа сэргээх мөч' Эдгээр нь зайлшгүй шаардлагатай мөчүүд юм.
WinAPI дээр энгийн цонх үүсгэхийн тулд ангийн бүтцийг бөглөж, бүртгүүлж, жижиг цонхны процедурыг бичих шаардлагатай байдаг тул гурав, дөрөв дэх төслийн дараа би C++ дээр бичсээр байгаагаа ойлгосон.
Үүний үр дүнд би энгийн ангиас бүх зүйлийг шүүрэн авсан. Цонхны бариул, цонхны нэр, ангийн нэр, цонхны процедурын хаяг, цонхны анги (WNDCLASS) бүгд хувийн ангийн хэсэгт хадгалагдана.
Тэдгээрийг задлахын тулд та энгийн "Авах" аргыг тайлбарлах хэрэгтэй, жишээлбэл:
HWND GetHWND()
LPCTSTR GetClsName() гэх мэт.
Цонхны ангиллыг шинэчлэх, бүртгэх, цонхыг өөрөө үүсгэх, харуулах ажлыг дизайнер гүйцэтгэдэг.
Ажлыг хөнгөвчлөхийн тулд та бүтээгчийн цагийн хуваарийг өөрчилж, цонхны ангийн бөглөх, бүртгэлийг тухайн ангийн хувийн функц болгон хувиргаж, бүтээгч бүрээс дуудаж болно. Урвуулах давуу тал нь заримдаа бүрэн энгийн цонх үүсгэх шаардлагатай байдаг бөгөөд би цонхны нэр ба програмын хойд хэсэг гэсэн хоёр параметр бүхий бүтээгч дээр дардаг.
Үгүй бол анхдагч цонхны процедур болон бусад хэв маягаар биш, тусгай хэмжээтэй цонх үүсгэх шаардлагагүй - би холбогдох параметрүүдтэй бүтээгч дээр дарна.
Энэ анги нь IDE-ийн оруулах хавтсанд байгаа шууд орсон файлд бага утгатай байна.
Энэ ангийн загвар:
анги BaseWindow
{
WNDCLASSEX_wcex;
TCHAR_ангийн нэр;
TCHAR_цонхны нэр;
HWND_hwnd;
bool _WindowCreation();
олон нийтэд:
BaseWindow(LPCTSTR цонхны нэр, HINSTANCE hInstance, DWORD загвар, UINT x, UINT y, UINT өндөр, UINT өргөн);
BaseWindow(LPCTSTR цонхны нэр, HINSTANCE hInstance);
const HWND GetHWND()const(HWND буцаана;)
LPCTSTR GetWndName()const(_windowName буцаана;)
};

Нэгэнт бодож, ийм хичээл бичсэн бол та амьдралаа хөнгөвчлөх бөгөөд нэг зүйлийг нэг дор бичих эхлэлийг эзэмшиж, хурцлахад цаг гаруй хугацаа зарцуулах болно. Тим илүү, би үүнийг илүү сайхан хүндэтгэдэг - ийм ангиудыг өөрөө бий болгож, өөрийн хэрэгцээнд нийцүүлэн нөхөх.

P.S.

Тодорхойлсон бүх зүйл нь үнэн юм:
Платформ - Windows 7 32 бит
IDE - Visual Studio 2010
Магадгүй хэн нэгэн инээд, ёжтой дуудахыг хүсч магадгүй, гэхдээ бид бүгдээрээ шинэхэн/дадлагажигч/бага насныхан гэж боддог байсан.
Нийтлэлийнхээ өмнө болгоомжтой байхыг би танаас хүсч байна. Бүтээлч шүүмжлэл мэдээж нисдэг. Үйлдлийн систем (OS)