Panimulang tutorial ng WTL mula sa simula

Wtl Introductory Tutorial From Scratch



Ang pangkat ng proyekto ay nagsusumikap upang mabuo ang proyekto ng platform ng Win platform kamakailan. Bagaman isa akong developer ng mobile, bilang isang developer, hindi ko dapat limitahan ang aking kakayahang magtrabaho para sa platform ng pag-unlad, kaya nagtagal ako upang makilahok sa Win client sa isang tiyak na lawak. Trabaho sa pag-unlad.

Bakit WTL

Ang proyekto ay ang control terminal software ng toB, ang pakete ng programa ng WTL ay maliit, at mayroon lamang isang file na EXE. Ito ay katugma sa iba't ibang mga bersyon ng operating system. Gumagamit din ang mga customer ng B-end ng XP, at maginhawa upang mai-publish at gamitin.



Bakit isulat ang artikulong ito

Ang WTL ay batay sa template upang ma-encapsulate ang window, malapit sa ilalim ng system, at may mataas na kakayahang umangkop. Gayunpaman, mahirap mabuo dahil sa kakulangan ng data. Hindi ko ipakikilala ang pinagmulan ng WTL. Ang mahalagang bagay ay kung naghahanap ka para sa WTL sa Internet, Mahahanap mo lang ang iba't ibang mga ad at isinaling bersyon ng artikulong ito ng WTL para sa MFC Programmers. Kung wala kang pundasyon ng MFC, mukhang magkakaroon ka ng ilang mga paghihirap, at kagaya ko nang wala ang C ++ na pundasyon, mas masakit ito sa ulo. Bilang isang IOS, mayroon akong isang mahusay na pundasyon ng wikang C. Gumagamit din ang Objective-C ng maraming C ++ - tulad ng syntax. Kaya't ginugol ko ang tungkol sa isang linggong pag-aaral ng C ++ at isang linggo upang pamilyar sa pinaka pangunahing balangkas ng WTL at ilang araw upang maunawaan ang balangkas ng proyekto ng kumpanya. Matapos ang komposisyon, magsimula at kumpletuhin ang gawain ng pag-screw ng maraming mga module ng interface. Ang artikulong ito ay tiyak na hindi sapat upang gawin kang taong namamahala sa proyekto ng WTL, ngunit dapat itong makatulong sa iyo na makapagsimula.



Ano ang pag-uusapan sa artikulong ito

Ang paggamit ng WTL para sa Win window interface program development ay pangunahin na bahagi ng UI, pangunahin kasama ang mga sumusunod na bahagi



  1. Pag-configure ng kapaligiran
  2. Lumikha ng unang window
  3. Pasadyang pagguhit
  4. Pangunahing mga kontrol: CButton CEdit CScrollerBar
  5. Dynamic at gumamit ng layout ng pahina ng mapagkukunan ng mapagkukunan
  6. Gumawa ng isang pasadyang kontrol
  7. Pagpapahusay ng extension ng WTL-DDX
  8. Pundasyon ng STL (nasa ilalim ng konstruksyon)
  9. Kontrolin ang synthesis (nasa ilalim ng konstruksyon)

Ano ang kailangan mong ihanda nang maaga?

Kailangang malaman muna ang C ++? Kailangan bang tingnan muna ang MFC? Wala, ngunit kailangan mo ng hindi bababa sa:
1. Magkaroon ng pundasyong C wika.
2. Maunawaan ang pagbuo ng programa na nakatuon sa object, maging C ++ o JAVA, OC o SWIFT at iba pang mga wika na may pag-unlad na nakatuon sa object, maunawaan ang OOP.
3. Kung wala kang pundasyon ng C ++, magagawa mo ito sunud-sunod ayon sa aking code. Tungkol sa mga tampok na naka-orient na object ng C ++ tulad ng maraming mana, template ng programa, atbp. Naroroon din ako Gumawa ng isang simple at madaling maunawaan na paliwanag sa lugar, at ang iba pang mga materyal na binuo ng C ++ ay mas detalyado. Kung may isang bagay na hindi mo maintindihan, Baidu.
4. Kung mayroon kang ilang pangunahing pag-unlad ng client ng IOS / Android, makakatulong ito.
5. Kung ikaw ay isang developer ng MFC, maaari kang direktang tumingin sa WTL para sa MFC Programmers.

Mas mahalagang impormasyon

Bilang isang tutorial para sa layunin ng pagpapakilala, hindi ko ipakikilala ang labis na mga pag-andar ng system ng Windows at lahat ng uri ng mga kumplikadong kontrol
Kung kailangan mo ng nauugnay na impormasyon, ang opisyal na dokumentasyon ng Microsoft ang pinakamahusay na sanggunian
https://docs.microsoft.com/en-us/cpp/mfc/referensi/mfc-class?view=vs-2019
Ang WTL ay batay sa ATL, ang karamihan sa mga klase sa ATL ay karaniwan sa MFC, kaya ang opisyal na dokumento ng klase ng MFC ay isang sanggunian at halaga ng pag-aaral na napakataas at kahit na nakuha ang maraming mga ad ay hindi Ididirekta ka sa opisyal na dokumentasyon
Narito ang download address ng WTL
https://sourceforge.net/projects/wtl/
Ang proyekto ng WTL ay mayroon ding ilang mga gawain para sa sanggunian.
# Opisyal na tutorial sa pagsisimula

Pagtatayo ng proyekto

  1. Mag-download at mag-install ng VS. Gumagamit ako ng Visual Studio 2015 kumpara sa bersyon ay may maliit na epekto sa WTL, ang default na pagsasaayos ay maaaring.

2. I-download ang WTL at alisin ang isama ang folder, ito ang lahat ng mga file na WTL na kinakailangan ng proyekto
WTL
3. Lumikha ng isang walang laman na proyekto sa CS sa VS
imahe
4. Magdagdag ng isang sanggunian sa WTL sa proyekto
WTL
5. Lumikha ng Main.cpp file at stdafx.h file. At isulat nang hiwalay ang sumusunod
imahe



//stdfax.h: #define STRICT #define WIN32_LEAN_AND_MEAN //#define _WTL_USE_CSTRING #include #include #include extern CAppModule _Module #define _WTL_NO_CSTRING #include #include #include #include #include #include #include // main.cpp: #include 'stdafx.h' CAppModule _Module int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { _Module.Init(NULL, hInstance) MSG msg while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg) DispatchMessage(&msg) } _Module.Term() return msg.wParam }

Ito ay karaniwang nakapirming pagsulat. stdfax.h bilang isang pampublikong header file, ipakilala ang kinakailangang file na WTL, dahil ang isama ay kopyahin ang code ng kaukulang file sa kasalukuyang file, kaya't bigyang pansin kung hindi mo alam kung ano ang nangyayari, huwag baguhin ang sanggunian ng pagkakasunud-sunod, kasama ang mga makro utos na nakapasok sa posisyon na ito.
Main.CPP ang pasukan ng programa. Ang CAppModule _Module ay isang halimbawa ng pag-save ng pangunahing thread ID at loop ng mensahe.

while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg) DispatchMessage(&msg) }

Ang pag-ikot na ito ay ang pangunahing siklo ng mensahe at kinokontrol ang ikot ng buhay ng application. Ang pagpapatakbo ng Win program ay nakasalalay sa mekanismo ng mensahe. Gamitin mo lang para maintindihan. Dito, hangga't alam mo na naipasok mo ang linyang ito, magsisimulang ipatupad ang programa sa loop ng mensahe at mabuhay. Samakatuwid, kinakailangan upang ipasok ang pasukan ng operasyon bago ito.
Ang pangunahing kapaligiran sa pagpapatakbo ng programa ay naka-set up dito. Ang WTL ay talagang isang hanay ng mga pakete na naglalarawan sa interface ng WinAPI, na maaaring madaling mapalawak o ipakilala sa ibang mga proyekto.

Simulang lumikha ng iyong sariling window

Matapos makumpleto ang pangunahing pasukan ng proyekto, maaari kang magsimula upang lumikha ng iyong sariling window sa pamamagitan ng WTL. Bago ito, kailangan kong ipaliwanag ang ilang mga konsepto. Kung pamilyar ka sa C ++, maaari mong laktawan ang bahaging ito.

1. Mga variable sa C ++.

Kung wala kang isang C ++ na pundasyon pagkatapos ay kailangan mong linawin ang ugnayan sa pagitan ng mga variable at bagay sa C ++.
Para sa mga variable, naglalaan ito ng memorya sa stack kapag nilikha ito. Ang mga bagay sa C ++ ay maaaring direktang nilikha bilang pangunahing mga uri. Ang memorya ay inilalaan kapag nilikha ito at na-pop out ang stack kapag umalis ito sa saklaw. Maaari ka ring lumikha ng isang bagay sa tambak na lumilikha ng isang pointer sa bago

void founction(){ yourClass obj1 yourClass *obj2 = new class }//obj1 release, obj2 pointer release, *obj2 object memory overflow
2. Template.

Ang WTL ay batay sa pagbuo ng template, at ang mga template ay ang pundasyon para sa pangkaraniwang programa. Maaari mong isipin ang isang template bilang isang paraan upang ilarawan ang isang uri ng object na sumusunod sa uri ng deklarasyon ng object na uri ng template.
Kumuha ng halimbawa

//A simple class A class A { void functionA(){ } } //A simple class B class B { void functionB(){ } } //A simple class P class P { void functionP(){ } } //Preparing a class C that follows the T template template//Declare the template class C:public T{ void functionC(){ } } //Define Class D yourself class D :public C { } //D is a class containing three methods of functionC and functionA. This description indicates that D inherits from C and C inherits from A. //Define Class E yourself class E :public C { } //E is a class containing functionC, functionB

Maaaring gamitin ang mga template upang ilarawan ang isang relasyon sa mana, na maaaring magamit upang tukuyin kung kanino nagmana ang isang bagay

//Customize a class F template//Declare the template and annotate its type class F :public T{ void functionF(){ //Call the functionP that you inherited. The class inherited from F must specify its template parameters as P and P subclasses functionP() } //Or for method //Create an R type object and call its focalP method template void founctionF2(){ R objR objR.founctionP() } void functionF3(){ //The subclass of P or P must be used when calling founctionF2

() } }

Ang paggawa nito ay katumbas ng paglikha ng a F Klase at tukuyin na nagmamana ito mula sa T Klase, at T Dapat maging a P Subclass ng dahil tayo F Direktang ginamit sa P Paraan.
Pangunahin ang template para sa mga serbisyong polymorphic. Masidhing pinahusay ang kakayahang magamit muli ng code.
Ang mga template ng WTL ay pangunahing ginagamit upang ideklara ang uri ng mana ng mga pasadyang kontrol.

Tatlo. Pag-andar ng virtual

Para sa mga pagpapaandar sa isang klase virtual Keyword, ang pagpapaandar na ito ay isang virtual function

virtual void founction(){}//Virtual function virtual void founction() = 0//Pure virtual function

Ang virtual na mga pag-andar ay maaaring isaalang-alang bilang isang deklarasyon ng interface.
Ang dalisay na virtual na pag-andar ay higit sa isang naglalarawang layunin. Tinutukoy nito na ang klase na naglalaman ng purong virtual function ay ang batayang klase. Hindi ito maaaring gamitin nang direkta ngunit sa pamamagitan lamang ng mga subclass nito.
### Bumalik sa WTL
Matapos maunawaan ang tatlong puntos sa itaas, maaari mong simulang maunawaan ang pangunahing mga tool para sa pagbuo ng interface ng WTL.
Sa Win program, ang lahat ng mga elemento ng interface ay CWindow . Ang pinaka-pangunahing uri ng interface sa WTL ay CWindowImpl .
Bago mo simulang gamitin ito, maintindihan muna natin sandali CWindowImpl
CWindowImpl

Mayroon itong tatlong mga parameter ng template T Pasadyang klase TBase Ito ang klase sa window sa WinAPI. Ang TWinTraits ay isang template ng setting, maaari mo itong balewalain nang hindi ginagamit ito.
Mula sa kahulugan nito, maaaring makita ang dalawang mga generic na parameter TBase Ginamit para sa paglipat ng uri, T Ginagamit para sa mga lokal na tawag, hayaan CWindowImpl Maaaring tawagan ang ilang mga pamamaraan ng klase ng iyong pasadyang klase, kung pinalalampas mo ang mga pamamaraang ito. Ang pag-iwas sa mga subclass mula sa pag-override sa mga pamamaraang ito ay tinatawag pa rin ang mga pamamaraang ito ng magulang na klase.
Pagkatapos ay tumingin
TWindowImplBaseT
ibinigay dito Tbase pati na rin ang TWinTraits Samakatuwid ang paunang halaga ay walang error kung hindi mo isusulat ang dalawang mga parameter na ito. Pangunahing itinuturo ng klase na ito ang ilang mga default na katangian ng window. Hindi mo na kailangang pangalagaan siya. Susunod na ito ay TBase Ipasa kay CWindowImplRoot . Pagkatapos ay tumingin.
CWindowImplRoot
Kaya't natagpuan namin ang pangwakas na patutunguhan at naipasa ito rito TBase Tinutukoy ang aktwal na batayang klase ng pasadyang kontrol.
at nagmamana rin ito mula sa CMessageMap Gagamitin ito sa lalong madaling panahon. Tingnan muna natin ito.
CMessageMap
sa CMessageMap Tinutukoy ang isang purong virtual function sa ProcessWindowMessage . Dito natin dapat gamitin CWindowImpl Subclass at dapat ipatupad ProcessWindowMessage paraan CMessageMap Malapit na nagbibigay ng isang hanay ng mga macro command upang makamit ang pagpapasa ng mensahe at mensahe. Pag-uusapan ko ito mamaya.
Isaayos:
minana mula sa CWindowImpl Kailangang pumasa ang klase ng hindi bababa sa tatlong mga parameter ** sa kanila T Para kay CWindowImpl paglipat TBase dapat CWindow At ang mga subclass nito, na may mga default na halaga CWinodw **, ang aktwal na paggamit ay upang pumasa sa huling sa CWindowImplRoot At minana ng ito bilang batayang klase ng pasadyang klase. TWinTraits Mayroong mga default na halaga para sa mga setting ng estilo.

Tukuyin ang unang pasadyang window

imahe
nilikha a FirstWindow Class, ito ay isang pangunahing bagay na WTL. Mana mula sa CWindow .
Kasi CMessageMap Umiiral ang purong virtual na pag-andar, kaya dapat itong idagdag
Ipinapatupad ito ng macro command.

BEGIN_MSG_MAP(FirstWindow) END_MSG_MAP()

Ang mga ito ay awtomatikong nilikha na konstruktor at mga destruktor. Kung walang pangangailangan, maaari itong matanggal.

FirstWindow() ~FirstWindow() FirstWindow::FirstWindow() { } FirstWindow::~FirstWindow() { }

Sa proyekto ng pagsasanay, maaari mong isulat ang lahat ng code sa .h file.
### ### Pagkatapos gamitin ito
sa WinMain Sa pagpapaandar, Moudle Pagkatapos ng paglikha, lumikha at ipakita ang window na ito bago magsimula ang loop ng mensahe
FirstWindowImpl

sa kanila CRect Ito ay isang bagay na naglalarawan sa laki ng posisyon. Maaari mong itakda ang posisyon ng itaas, ibaba, kaliwa, at kanang bahagi na may kaugnayan sa kontrol ng magulang.
Kailangang tumawag pagkatapos lumikha ng object ng Window Lumikha Paraan upang lumikha ng isang window
Ang pamamaraan ay may mga sumusunod na parameter

In_opt_ HWND hWndParent, //Handle of parent control _In_ _U_RECT rect = NULL,//Specify the position size _In_opt_z_ LPCTSTR szWindowName = NULL,//The window name will be displayed in the system bar in the upper left corner. The default style is visible _In_ DWORD dwStyle = 0,//Window style type, property setting _In_ DWORD dwExStyle = 0, //Window expansion style _In_ _U_MENUorID MenuOrID = 0U,//Resource ID, can be understood as the digital mark of the object, which will be used again when using the resource file later _In_opt_ LPVOID lpCreateParam = NULL // 16-bit machine legacy parameters. Not needed now

Dito ko maikling ipinaliwanag ang hawakan
Ang hawakan ay isang istraktura na kumakatawan sa isang mapagkukunan ng Window, na katumbas ng index nito. Ang mapagkukunang ito ay matatagpuan sa pamamagitan ng hawakan. Maaari ka ring magpadala ng isang mensahe sa pamamagitan ng hawakan. Nag-overload ang CWindow sa hawakan. Gawin ang pagpapatakbo ng pagtatalaga ng CWindow na hinayaan lamang ang paghawak ng pointer ng isa pang CWindow na object na tumuturo sa hawakan ng target na bagay. Tingnan lamang ito sa ngayon.
imahe

Ang hawakan na tinukoy sa Lumikha ng pamamaraan ay karaniwang ginagamit upang itakda ang posisyon ng kontrol, iyon ay upang sabihin tuwid Ang posisyon ng control na itinakda ng parameter ay kaugnay sa hWndParent ng Habang tinutukoy hWndParent Kapag walang laman, ang posisyon ng window ay may kaugnayan sa screen, Ang kaliwang sulok sa itaas ay 0.0 puntos, ang kanan / pababa ay ang positibong axis .
Sa puntong ito, ang code na idinagdag namin ay lumilikha ng isang X at Y axis mula sa kaliwang sulok sa itaas ng screen, simula sa 10 at magtatapos sa 500 FirstWindow Uri ng window. Tingnan mo
imahe
It seems that the left margin is more than the top. This is because the style of the system window has a border, which is distributed on the left and right sides. In Win10, it is a transparent style, about 8 pixels.
Ang window ay nawawala ang isang malapit na pindutan
maaaring malikha dwStyle Itakda ang parameter na ito sa mga pag-aari. maaaring magamit | Ang pagpapatakbo ng bitwise ay nagtatakda ng maramihang sabay. Maaari mo nang magamit ang X button upang isara ang window.

Window.Create(NULL, rc, 'HELLO WORLD',WS_VISIBLE | WS_SYSMENU,NULL,0U,NULL )

imahe

pero This does not close the program!
Itinatago lamang ng pag-click sa X ang window, ang mga programa ay pa rin loop sa pangunahing pamamaraan, at walang mga variable na inilabas.
imahe
Kung nais naming isara ang programa kapag isinara namin ang window, kailangan naming gamitin ang mekanismo ng mensahe.
Sa paraan ng lifecycle ng window ng WTL, ang pakikipag-ugnay sa interface ay may kaukulang mga mensahe na ipinamamahagi sa mga kaukulang klase. Ang pagtanggap at pagpapasa ng mga mensaheng ito ay naka-encapsulate sa isang serye ng mga macro command, na naipasok BEGIN_MSG_MAP kasama END_MSG_MAP At ipatupad ang kaukulang pamamaraan upang makatanggap ng mga mensahe
imahe
** Ang PostQuitMessage (0) ** ay WinApi na pamamaraan, maaari mong wakasan ang programa.
** Idineklara iyon ni ** MSG_WM_CLOSE (OnClose) ** SaClose Paraan upang makatanggap ng isang mensahe upang isara ang window.
The method name can be changed, but the method name in the original header file is generally used for reading
Ang parehong pangangatwiran ay maaaring maibawas, tulad ng paglikha ng window, paggalaw, oras ng pagguhit ng mouse, atbp. Ang isang malaking bilang ng life cycle / operasyon na kaukulang mga kaganapan tulad ng pamamahala ng system ay maaaring mapatakbo sa pamamagitan ng mekanismong ito
MSG
Maaari mong direktang mahanap ang kahulugan ng mensahe at mensahe parameter sa kaukulang file ng header.

Ngunit bigyang pansin iyon dapat mong tanggalin ang lahat ng mga bintana na nilikha mo bago tawagan ang pamamaraang ito upang wakasan ang application
WTL
** Maaaring sirain ng DestroyWindow () ** ang kasalukuyang window, o maaari mong punan ang isang hawakan ng window upang tanggalin ang tinukoy na window.
imahe
imahe
imahe

Pagguhit

Nang ipinanganak si WinApi, walang magandang pagtutukoy ng visual expression tulad ng Material Design. Ang istilo ng pagkontrol ng system ay medyo mahirap makuha at puno ng mga istilo ng disenyo ng engineer. Samakatuwid, sa karamihan ng oras, kailangang ipatupad ng mga kontrol ang pasadyang pagguhit, kahit na itinakda lamang nila ang kulay ng background.
Matapos makumpleto ang pinakasimpleng kontrol sa window sa itaas, magdagdag tayo ng isang kulay ng background dito.
Ang pamamaraan ng pagguhit ay tinatawag kapag na-update ng system ang kontrol. Samakatuwid depende rin ito sa loop ng mensahe. Mahahanap namin ito sa kahulugan ng file ng mensahe.
imahe
at SaClose Ang parehong paraan ng pagdaragdag
OnPaint
Ang mga parameter ng pamamaraan CDCHandle Ito ay isang bagay na ginamit para sa pagguhit ngunit hindi namin direktang magagamit ang parameter na ito.

Maikling pag-aralan ang bagay sa pagguhit

Pumunta sa CDCHandle Kahulugan
CDCHandle
Maaari mong makita na siya ay isang CDCT Mga alias para sa iba't ibang mga pangkalahatang parameter ng klase, mayroon ding kaukulang CDC klase
Susunod, tingnan mo CDCT Ang papel na ginagampanan ng mga pangkalahatang parameter
CDCT
pumasa CDCT Ang kahulugan ng ay maaaring makita sa mga generic na parameter t_bMamahala Isa ang idineklara CDCT Hawak ng object HDC Kung ang bagay ay pinamamahalaan ng iyong sarili, at pagkatapos CDCT Wasakin kapag nawasak HDC .
dito HDC Ay isang hawakan na tinukoy ng WinApi para sa pagguhit.
Sa madaling sabi, ito ay sa Ang hawakan na hawak ng tagabalot ay maaaring maipasa ng halaga, nang hindi nakakaapekto sa hawakan. Ngunit ang panghuling hawakan ay masisira lamang kapag sinira ito ng tagalikha
Of course it doesn't matter if you don't understand. Just know what you should do next.
gamitin CPrintDC Klase, na tinukoy sa ATL upang makuha mula sa hawakan ng window HDC Hawakan
Tingnan mo CPrintDC Kahulugan
CPrintDC

gamitin CPrintDC
imahe
HBRUSH Ay isang tool ng brush na ibinigay ng WinApi LumikhaSolidBrush Ay upang lumikha ng isang monochrome brush, dito lumikha kami ng isang Proteksyon ng kulay naPaintbrush
GetClientRect Kunin ang posisyon ng kasalukuyang kontrol na may kaugnayan sa sarili nito. Iyon ay ang kanilang sariling sukat. Pumasa isa CRect Magtalaga ng isang halaga dito.
FillRect Pagkatapos ang brush ay itinalaga sa kaukulang lugar. Iyon ang pagpapatakbo ng pagguhit.
imahe

Dynamic na pagguhit

Kung nakipag-ugnay ka sa interface API ng iba pang mga platform, dapat na direktang maiisip mo ang mga sumusunod na punto ng pansin:
Ang operasyon ng pagguhit ay maaari lamang tawagan ng system Ang pamamaraan ng pagguhit ay isang pamamaraan ng isang tukoy na pagpapatupad ng proseso. Hindi aktibong tumawag
Halimbawa, ang mga sumusunod na operasyon
Magdagdag ng isang kaganapan sa pagtugon sa pag-click sa mouse sa pamamagitan ng mensahe, na tatawagin kapag ang kaliwang pindutan ng mouse ay na-click sa window OnLbuttonDown
Idagdag ang operasyong nais mong gawin dito
imahe

Di-wasto () Ang pamamaraan ay isang pamamaraan na maaaring magamit upang mai-update ang kontrol. Hindi mapatunayan nito ang kontrol at maa-update ng system sa idle time.
UpdateWindow () Ang pamamaraan ay maaaring gumawa ng di-wastong pag-refresh ng kontrol kaagad, at ito ay muling mababago. Kung hindi mo kailangang i-refresh kaagad, hindi mo kailangang idagdag ito.
Tulad ng nakikita mo, hindi mahalaga kung ang brush ay direktang ginamit o ang OnPaint na pamamaraan ay tinatawag na panlabas, ang kulay ng interface ay hindi nagbago.
imahe
Ang interface ay nagiging asul, sa katunayan, awtomatiko itong tinatawag ng system
OnPaint
Ang pamamaraan ay magkakabisa pagkatapos.
Susunod na ginagamit ko ang code na ito upang maipakita ang proseso
imahe
The black square is missing because the GIF recording will lose frames
Ang idinagdag na code ay unang kumukuha ng background kapag ang mouse ay na-click at pagkatapos ay gumuhit ng isang itim na tuldok sa paligid ng mouse. Kapag ang mouse ay itinaas, kanselahin ang posisyon ng itim na tuldok, at pagkatapos ay i-update muli ang pagguhit.
Pagkatapos ay magdagdag ng isang maliit na pag-andar
magsipilyo
CPen
At pagguhit ng teksto
imahe

void printLine( CDCHandle dc) { CPen pen pen.CreatePen(PS_SOLID, 2, RGB(255, 255, 255)) dc.SelectPen(pen.m_hPen) CPoint start start.x = 10 start.y = 10 dc.MoveTo(start) CPoint dest dest.x = mouseClickLocation.left dest.y = mouseClickLocation.top if (dest.x != 0) { dc.LineTo(dest) } } void printText(CDCHandle dc) { CString text CRect textLocation text = 'hello world' dc.SetTextColor(RGB(0, 0, 0)) dc.ExtTextOutA(mouseClickLocation.left, mouseClickLocation.top, ETO_OPAQUE, NULL, text, text.GetLength(), NULL) }

Pangkalahatang pagsasalita kung tama ka CPringDC Kung ang tawag ay isang malayang pagguhit
Dapat mo itong gamitin bago gumuhit SaveDC I-save at tawagan ito sa dulo
Ibalik angDC (-1) Paraan upang maibalik ang iyong dating estado
DC
Napansin mo siguro na meron na ako OnPaint Kapalit ng pamamaraan para sa DoPaint Paraan, na nagsasangkot ng isang punto na idaragdag sa susunod

CDoubleBufferImpl

Kung muling ididraw mo nang paulit-ulit sa panahon ng pagguhit, ang isang bahagi ng guhit ay iguguhit dahil sa pagguhit. Kung ang redraw ay masyadong mabilis, ang susunod na pagguhit ay gaganapin bago makumpleto ang nakaraang pagguhit, na magiging sanhi ng flicker.
imahe
Kailangan mong gamitin ito ngayon CDoubleBufferImpl , Ito ay dinisenyo bilang isang magulang na klase, kaya kailangan mong gumamit ng maraming pamana kapag nais mong gamitin ito.
Una tingnan ang pagpapatupad nito
CDoubleBufferImpl
CDoubleBufferImpl Nakatanggap ito ng mensahe na tatawagan nito ang pagguhit. Pagkatapos ay nagbibigay ng isang interface DoPaint
Kaya gamitin ito tulad nito
1. Magdagdag ng mana ng klase
imahe
2. Magdagdag ng isang link ng mensahe
imahe
CHAIN_MSG_MAP Maaari mong i-link ang mga mensahe sa kaukulang klase sa kasalukuyang klase
Kasi CDoubleBufferImpl Nakamit na MSG_WM_PAINT (OnPaint) , Kaya't kailangang ma-comment ito.
3. Pagpapatupad DoPaint paraan
Iyon ay, ilagay ang lahat ng kailangan mo upang gumuhit dito. DC Nandito na CDoubleBufferImpl Ay nakuha at ipinasa sa DoPaint , Kaya direkta lang itong gamitin.
DoPaint
Tingnan ang epekto
CDoubleBufferImpl
In the case of mouse movements, complex drawing may lead to drawing errors, which may be caused by the high return rate of the mouse (the high-end mouse can reach 1000HZ). The call to drawing exceeds the rendering ability of the GPU. In this case, it is necessary to actively reduce the drawing frequency, such as the scheme limited to 60 frames, and the independent windows are drawn independently, so try to avoid a large number of custom drawing windows to redraw at the same time.
Tungkol sa pagguhit, wala nang extension dito.
## Dynamic na pagbuo ng mga pangunahing kontrol
Bago ang karagdagang paggamit ng mga nakabalot na kontrol sa WTL, kailangan mong maunawaan at gumamit ng ilang pangunahing mga kontrol sa MFC.
Ang proseso ng pagdaragdag ng mga kontrol ng bata sa isang pasadyang kontrol ay karaniwang inilalagay sa mensahe ng paglikha sa pamamaraang lifecycle. Para sa CWinodwImpl ay MSG_WM_CREATE
imahe

CButton

Lumikha ng isang CButton para sa FirstWindow
Tandaan na para sa isang pag-kontrol sa bata, kailangan mong tukuyin ang hawakan ng kontrol ng magulang upang matukoy ang posisyon ng coordinate system. Sa parehong oras, kailangan mong itakda ang istilo sa WS_CHILD o WS_CHILDWINDOW (ang dalawa ay katumbas).

int OnCreate(LPCREATESTRUCT lpCreateStruct) //TODO: add control CButton btn CRect btnRect btnRect.left = 50 btnRect.right = 150 btnRect.top = 50 btnRect.bottom = 100 btn.Create(m_hWnd, btnRect, 'ClickBtnHere', WS_VISIBLE

imahe

Magdagdag ng mga kaganapan sa pagtugon

Ang mga kaganapan sa pagtugon ng pindutan ay ipinapasa sa mekanismo ng mensahe
pumasa CommAND_HANDLER Idinagdag ang utos ng Macro
imahe
Tandaan na ang mga parameter na minarkahan ng mga pulang arrow ay nagpapahiwatig ng control ID na naaayon sa mensahe, at tatawagin lamang kung tumutugma sila.
Upang maiwasan ang mga dobleng ID at mapahusay ang kakayahang mabasa ng code, ang ID ng kontrol ay idinagdag sa pamamagitan ng isang file ng mapagkukunan.
Buksan ang window ng mapagkukunan sa menu
imahe
Hanapin ang iyong proyekto. rc entry na right-click menu at i-click ang simbolo ng mapagkukunan
imahe
Piliin ang Bago at magpasok ng isang pangalan
imahe
Dahil ito ay isang macro command, ang istilo ng pagbibigay ng pangalan ng underscore na dibisyon ay karaniwang nakasulat sa buong kabisera
Ang pangunahing pag-andar ng simbolo ng mapagkukunan ay hayaan ang iyong kontrol na tumugma sa kaukulang hawakan ng ID sa mekanismo ng mensahe. Ang mga kontrol na nilikha ng pabago-bago ay maaari ring matagpuan nang direkta sa pamamagitan ng hawakan. Kaya't ang mga mapagkukunan ay pangunahing ginagamit para sa mga pananaw na nilikha nang statically sa pamamagitan ng XML. Ang bahaging ito ay ipapaliwanag sa paglaon kapag pinag-uusapan natin ang tungkol sa layout ng mga kontrol.
CommAND_HANDLER Tatawagan ang isang pamamaraan na may apat na mga parameter at isang pabalik na halaga
CommAND_HANDLER
Magdagdag ng kaukulang paraan ng pagtugon
imahe
Sa tugon, nakita ko ang pindutan at binago ang pamagat ng pindutan sa pamamagitan ng hawakan na ipinasa ng pamamaraan ng tawag sa system, at binago ang background ng buong window sa pamamagitan ng pagtutugma ng kaukulang pindutan sa ID
imahe
Maaari ka ring pumasa GetDlgItem Paraan upang makuha ang hawakan ng kontrol
GetDlgItem
Tandaan na ang mga hawakan lamang ng mga kontrol ng bata ng kontrol na tumatawag sa pamamaraang ito ang maaaring makuha, iyon ay, kapag nilikha ang mga ito hWndParent Ang parameter ay tinukoy bilang kontrol ng kontrol.

Magbunga

Kontrol ng input box, nilikha din sa pamamagitan ng Lumikha ng pamamaraan

CEdit textField CRect tfRect tfRect.left = 200 tfRect.right = 300 tfRect.top = 50 tfRect.bottom = 100 textField.Create(m_hWnd, tfRect, nullptr, WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_AUTOVSCROLL, 0UL, 0U, NULL)

Itakda ang pag-aari sa pamamagitan ng parameter ng Estilo. Bilang default, ito ay isang solong linya. Ang ES_MULTILINE ay nakatakda sa maraming mga linya, at ang ES_AUTOVSCROLL ay nakatakda sa patayong awtomatikong pag-scroll. Bilang default, ito ay isang solong linya. Kung hindi mo itinakda ang pag-scroll, hindi mo na tatanggapin ang mga input character kapag pinunan ng mga character ang control.
imahe

Kunin ang nilalaman ng teksto ng input box

SetWindowText Pamamaraan at GetWindowText Maaari mong itakda / makuha ang nilalaman ng character sa Cedit ayon sa pagkakabanggit.
imahe

CScrollBar

Ang CScrollerBar mismo ay ginagamit bilang isang independiyenteng kontrol, ngunit ang CWindow ay may isang default scroll bar na maaaring magamit. Itakda lamang ang WS_VSCROLL / WS_HSCROLL sa Estilo.

CScrollBar scroller CRect scrRect scrRect.left = 20 scrRect.right = 40 scrRect.top = 20 scrRect.bottom = 200 scroller.Create(m_hWnd, scrRect, '', SBS_VERT | WS_VISIBLE |WS_CHILD, NULL, 0U, NULL) this->ShowScrollBar(0, 1)//Show horizontal scroll bar this->ShowScrollBar(1, 1)//Show vertical scroll bar

SBS_VERT Itakda ang direksyon ng scroll bar upang maging patayo. Ang default ay pahalang
imahe

Itakda ang mga pag-aari para sa scroll bar
SCROLLINFO info scroller.GetScrollInfo(&info) scroller.SetScrollInfo(&info, false) scroller.SetScrollRange(0, 100) scroller.SetScrollPos(20, TRUE)

ni SCROLLINFO Itakda ang mga halagang kinakatawan sa magkabilang panig ng scroll bar
Ang scroll bar mismo ay hindi titigil sa kaukulang posisyon sa pag-scroll, hanggang sa pamamagitan lamang Mga SetScrollPos Paraan upang ihinto ito sa kaukulang posisyon.
imahe
Samakatuwid, kailangan mong i-record at itakda ang scroll bar upang manatili sa kaukulang posisyon sa kaganapan ng pag-scroll
Magdagdag ng kaganapan ng scroll bar scroll
Magdagdag muna ng mensahe MSG_WM_VSCROLL (OnVScroll)
Pagkatapos ay idagdag ang paraan ng pagtugon

void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) { int curPos = pScrollBar.GetScrollPos() int destPos = curPos switch (nSBCode) { case SB_THUMBPOSITION: destPos = nPos break } pScrollBar.SetScrollPos(destPos) }

nSBCode Ito ang uri ng marka ng kaganapan ng scroll bar, kasama ang pag-scroll sa lahat ng direksyon, pag-drag ng mouse, pagsisimula, paghinto, atbp. Magdagdag muna ng isang simpleng kaganapan
SB_THUMBPOSITION Ito ay napalitaw kapag na-drag ng mouse ang slider sa isang tiyak na posisyon at binubuhat
imahe
Para sa iba pang mga kaganapan, ang parameter ng nPos ay 0 at kailangan mong idagdag ang kaukulang operasyon ng pagbabago sa tugon
imahe
Mag-ingat na huwag hayaan ang posisyon ng target na lumampas sa saklaw na iyong itinakda

CComboBox

CComboBox box CRect lstRect lstRect.left = 50 lstRect.right = 150 lstRect.top = 120 lstRect.bottom = 200 box.Create(m_hWnd, lstRect, 'listCtrl', WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST, 0UL, 0U, NULL) box.AddString('item1') box.AddString('item2') box.AddString('item3')

Magtakda ng iba't ibang mga estilo ay magkakaroon ng iba't ibang mga estilo, maaari mo itong subukan mismo
CComboBox
Para sa mga halimbawa ng karaniwang ginagamit na mga kontrol, pag-usapan natin ang tungkol sa mga kumplikadong kontrol na ito tulad ng mga kontrol sa puno, mga pagpipilian ng file, at mga menu. Ang mas detalyadong impormasyon ay matatagpuan.

Layout ng window

Kapag binabago ang laki ng window, o nagpapalitaw ng mga kaganapan sa kontrol, kung minsan kailangan mong baguhin ang layout ng interface.
Maaari mong gamitin ang ** MoveWindow () ** na pamamaraan upang mabago ang posisyon ng kontrol
Maginhawa upang magamit Una ang tindahan ng kontrol bilang isang variable ng miyembro ng klase
Baguhin ang posisyon ng pindutan habang nag-scroll

void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) { int curPos = pScrollBar.GetScrollPos() int destPos = curPos switch (nSBCode) { case SB_LINEUP: destPos -= 1 break case SB_LINEDOWN: destPos += 1 break case SB_THUMBTRACK: destPos = nPos break case SB_THUMBPOSITION: destPos = nPos break } if (destPos 100){destPos = 100} pScrollBar.SetScrollPos(destPos) CRect btnRect btn.GetWindowRect(&btnRect) int W = btnRect.Width() int H = btnRect.Height() btnRect.top = destPos btnRect.bottom = destPos + H btnRect.left = 50 btnRect.right = 50 + W btn.MoveWindow(btnRect, TRUE)//The second BOOL value parameter specifies whether to redraw immediately }

imahe

Tumugon sa kaganapan sa pagbabago ng laki ng window ng magulang

Karaniwan ang laki ng posisyon ng kontrol ng mobile ay pangunahing ginagamit para sa makatuwirang layout kapag nagbago ang laki ng magulang window
Magdagdag muna ng istilo sa isang window WS_SIZEBOX Kaya maaari mong i-drag ang laki

Window.Create(NULL, rc, 'HELLO WORLD',WS_VISIBLE | WS_SYSMENU | WS_SIZEBOX,NULL,0U,NULL )

Pagkatapos tanggapin MSG_WM_SIZE balita
MSG_WM_SIZE
Ang pamamaraan ng OnSize ay tatawagan kapag nag-drag sa window, at ang kaukulang laki ay ipapasa sa laki ng parameter.

Kailangang magdagdag ng nilalaman ng point window at coordinate system

Karaniwan may dalawang paraan upang makuha ang posisyon sa window
Ang window ay may dalawang coordinate area, ang isa ay ang laki ng window mismo. Mayroon ding isang lugar ng gumagamit ng window, na isang bahagi ng lugar na maaaring mapatakbo ng gumagamit maliban sa hangganan.
GetWindowRect () Kunin ang posisyon ng window na may kaugnayan sa window ng magulang, na kung saan ay ang posisyon ng laki ng buong window
GetClientRect () Ang nakukuha mo ay ang posisyon ng lugar ng gumagamit ng window mismo, na laging 0.0 bilang panimulang punto. Sa katunayan, ito ay ang laki ng sarili nitong lugar ng gumagamit.
ScreenToClient () Maaaring i-convert ng pamamaraan ang nakuha na sistema ng coordinate sa ganap na posisyon sa kaukulang screen
Para sa mga kontrol ng bata, karaniwang pumasa
GetClientRect
Kunin ang lugar ng kontrol ng magulang sa layout, sa pamamagitan ng
GetWindowRect
Kunin ang posisyon ng iba pang mga kontrol ng bata sa ilalim ng parehong kontrol ng magulang. Ang mga posisyon na nakuha sa oras na ito ay may kaugnayang mga coordinate na may kaugnayan sa lugar ng gumagamit ng kontrol ng magulang.
at kung gusto mo Parehong mga kontrol ng magulang at anak ay na-convert sa parehong kaukulang sistema ng coordinate
kailangan mo munang tawagan ang kontrol na kailangang i-convert ang coordinate system mismo GetWindowRect At pagkatapos ay pinag-isa Kontrol ng magulang paglipat ScreenToClient Upang ibahin ang sistema ng coordinate, nakuha ang ganap na posisyon ng control na may kaugnayan sa screen.
Ang aplikasyon ng puntong ito ay gagamitin sa komprehensibong kasanayan sa layout na pupunan pagkatapos ng pagtatapos ng pangunahing nilalaman. Siyempre, lumikha ng ilang mga kontrol sa iyong sarili at subukang unawain na ito ay magiging mas malinaw.

Susunod, hayaan ang scroller na kumapit sa kaliwa sa OnSize

void OnSize(UINT nType, CSize size) { CRect clientRect GetClientRect(&clientRect) CRect scrRect scrRect.top = clientRect.top scrRect.left = clientRect.left scrRect.right = scrRect.left + 20 scrRect.bottom = clientRect.bottom scroller.MoveWindow(scrRect) }

OnSize

I-visualize ang layout gamit ang mga file ng mapagkukunan

Sa pagpapaunlad, ang interface ay kailangang maging kumplikado ngunit naayos na mga kontrol, na ang lahat ay gumagamit ng isang pabago-bagong pamamaraan ng paglikha na may isang malaking halaga ng code, kaya maaari din itong makamit sa pamamagitan ng pag-drag sa kontrol ng file ng mapagkukunan. I-drag lamang ang kontrol nang direkta sa nais na lokasyon sa pamamagitan ng mapagkukunan at gamitin ang resource ID upang makuha ito. Makatipid ng maraming code ng layout.
Gawin ang dialog box bilang isang halimbawa upang magsanay. Buksan ang view ng mapagkukunan, mag-right click at piliin ang magdagdag ng mapagkukunan
imahe
imahe
Mayroong maraming mga kaukulang uri at iba't ibang mga pag-andar, na maaaring direktang maunawaan ng Baidu. Dito direktang ginagamit namin ang pinaka pangunahing batayan ng Dialog. Hindi na kailangang buksan ang plus sign.
imahe
Ang ID sa pulang bilog ay ang mapagkukunang ID ng dialog box. Para sa kakayahang mabasa, binago ito sa isang naaangkop na pangalan. IDD_DIALOG_FIRST.
Maaari mo ring buksan ang panel ng pag-aari ng control sa pagpipiliang pag-click sa kanan ng mga dialog box upang maitakda
imahe
Ang panel ng mga pag-aari ay may ilang mga pagpipilian na maaaring maitakda. Maaari kang matuto nang kaunti sa iyong sarili.
Ang pangunahing diyalogo ay nagbibigay ng dalawang mga default na pindutan
imahe
Para sa independiyenteng kahon ng dayalogo, ito ay isang uri ng lalagyan, kailangan mong lumikha ng isang klase upang magbigkis at magpatakbo. Samakatuwid, ang resource ID nito ay hindi maaaring kapareho ng resource ID ng iba pang mga uri ng lalagyan, ngunit para sa kontrol ng bata sa lalagyan. Hangga't hindi na nauulit sa iisang lalagyan.
Sa oras na ito, gamitin ang ATL dialog class CDialogImpl (Katulad ng CWindow)
Idagdag sa kaukulang klase ng dayalogo

enum { IDD = IDD_DIALOG_FIRST//Resource ID }

Tukuyin ang pagbubuklod ng mapagkukunan.

#pragma once #include 'stdafx.h' #include 'resource.h' class FirstDialog :public CDialogImpl { public: enum { IDD = IDD_DIALOG_FIRST } BEGIN_MSG_MAP(FirstDialog) END_MSG_MAP() }

Sa ganitong paraan ginagamit namin ang kaukulang klase. Dadalhin nito ang nakagapos na window ng mapagkukunan
Bumalik muna sa resource file at buksan ang toolbox upang magdagdag ng mga kontrol sa window
imahe
imahe
Maaari kang makakita ng maraming mga kontrol, kung kailangan mong pumunta sa opisyal na dokumento o Baidu ayon sa pangalan, maaari kang makahanap ng detalyadong pagsusuri sa paggamit.
Magdagdag ng isang kontrol na StaticText at ipasa ito sa panel ng mga katangian Caption Text ng setting ng pag-aari
Gamitin ang klase na nilikha mo lamang upang makuha ang dayalogo na ito.
gamitin DoModal Dialog ng pop-up na paraan ng paraan
imahe
imahe
Tulad ng dati, ang mga kaganapan sa malapit at pindutan ay kailangang hawakan ng kanilang mga sarili, ngunit kapag gumagamit ng mga file ng mapagkukunan, maaari mong direktang idagdag ang kaukulang mga kaganapan sa pakikipag-ugnay sa pamamagitan ng file ng mapagkukunan, at ang pagtanggap ng mensahe at awtomatikong pagbuo ay awtomatikong mabubuo sa kaukulang file. Ang code ng kaukulang pamamaraan, ang pagpapatupad ng pamamaraan ay mabubuo at idaragdag sa .cpp, kaya unang lumikha ng kaukulang .CPP file na iyong sarili
CPP
Pumunta sa panel ng pag-aari ng kontrol at i-click ang kaganapan sa kontrol upang magdagdag ng isang tugon sa kaganapan sa pag-click
imahe
awtomatikong bubuo ng kaukulang code
imahe
imahe
gamitin EndDialog Paraan upang isara ang dialog box.
Maaari mong makuha ang kontrol sa pamamagitan ng ** GetDlgItem () **.

BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { GetDlgItem(IDOK).SetWindowText('BTNOK') return 0 } LRESULT FirstDialog::OnBnClickedOk(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // TODO: add control notification handler code here EndDialog(0) return 0 }

## Lumilikha ng mga pasadyang kontrol
#### Unang ipakilala ang isang WTL pinahusay na tool sa pagpapalitan ng data na DDX
Ang DDX ay isang hanay ng mga macro command na katulad ng MSG_MAP. Ang kakanyahan nito ay upang gawing simple at pinag-isa ang calling code na naglilipat ng mga halaga sa pagitan ng mga bintana at data.
ay medyo simpleng gamitin, halimbawa.
Unang manain sa klase na kailangang gumamit ng DDX CWinDataExchange ama
imahe
Pagkatapos ay gamitin ang utos ng DDX upang maiugnay ang ID ng kontrol na dapat na nakatali at ang variable ng kaukulang uri
imahe
Siyempre, upang lumikha ID_TF_FIRST Ang resource ID na ito ay nakatalaga sa CEdit na nilikha nang mas maaga
Pagkatapos gamitin ito sa lugar kung saan kailangang palitan ang data
** DoDataExchange () Maaaring ipasa ng mga pamamaraan ang data mula sa mga variable patungo sa mga kontrol, o Ang DoDataExchange (TRUE) ** ay ipinasa mula sa control patungo sa variable
imahe

imahe
DDX
Maaari mong tukuyin ang iyong sariling DDX macro sa pasadyang kontrol, upang madali mong pag-isahin ang input at output, madaling basahin ang code.

Gumamit ng mga file ng mapagkukunan upang i-set up ang mga pasadyang view

Madaling lumikha ng isang pasadyang pagtingin gamit ang purong code, at magagawa ang mana.
Kung nais mong lumikha ng isang control ng drag nang hindi gumagamit ng code, kailangan mong gamitin ang kontrol ng Custom Control, irehistro ito bago gamitin, at gumamit ng isang pasadyang pag-uugnay sa klase ng window.
I-drag muna ang isang mapagkukunan ng uri ng CustomControl sa kaukulang view, pagkatapos ay tukuyin ang isang resource ID at ipasadya ang isang Pangalan ng klase.
imahe
Pagkatapos bumalik sa Pangunahing pagpapaandar at irehistro ang Klase na ito
imahe
Lumikha ng isang pasadyang klase ng window at iugnay ang mga mapagkukunan
imahe
Sa ganitong paraan, ang kontrol na kinakatawan ng mapagkukunan ay ang kontrol na naaayon sa iyong pasadyang klase. Kung kailangan mong lumipat sa isa pang window, maaari kang direktang gumana sa file ng mapagkukunan, hangga't gagamitin mo ang bagay at maaaring maiugnay ang Mga Mapagkukunan.
imahe

Magdagdag ng mga kontrol sa mga pasadyang pagtingin sa mapagkukunan

Ang paggamit ng isang pasadyang pagtingin sa mga mapagkukunan ay hindi kailangang tawagan ang paraan ng Lumikha, kaya't hindi ka makakalikha ng isang subspace dito, ngunit tatawagin ito kapag ang klase ay nakasalalay sa mapagkukunan SubclassWindow . Maaari mong isulat muli ang pamamaraan dito upang idagdag ang pagpapatakbo ng paglikha ng mga kontrol sa bata.

class FirstCustomItem :public CWindowImpl 。。。。。 CButton btnL CButton btnR BOOL SubclassWindow(_In_ HWND hWnd) { //First call the SubclassWindow of the parent class BOOL result = CWindowImpl::SubclassWindow(hWnd) if (result) WS_CHILD, 0UL, 0U, NULL) btnR.Create(m_hWnd, rRect, '0', WS_VISIBLE return result } } 。。。。。

Idagdag ang iyong sariling DDX

Ang DDX macro ay mahalagang isang tawag lamang sa pamamaraan, at ito ay talagang kapareho ng 'pagdaragdag ng isang input at output interface sa iyong sariling kontrol at manu-mano itong tumatawag'. Ang kahalagahan nito ay nakasalalay sa isang pinag-isang pahayag na maaaring hawakan ng pantay para sa isang klase ng input at output. Dahil ang C ++ code ay madalas na may maraming mga linya. Ang DDX ay mahalagang ginagawang mas madaling mabasa ang programa.
Magdagdag ng pamana ng klase CWinDataExchange

template class FirstDialogDDX : public CWinDataExchange { #define DDX_FD_TEXT(nID, var) if(nCtlID == (UINT)-1 || nCtlID == nID) { if(!ddxFdText(nID, var, sizeof(var), bSaveAndValidate)) return FALSE } void ddxFdText(UINT nID, CString& nValue, BOOL bSave) { //Get handle T* pT = static_cast(this) HWND hWndCtrl = pT->GetDlgItem(nID) ATLASSERT(hWndCtrl != NULL) //Send operation message if (bSave) { //Write } else { //take out } } }

Kung naalala mo ang nakaraang proseso ng pag-aralan ang iba pang mga bahagi, hindi ka pupunta sa DDX para sa pagtatasa, maaari mo itong tingnan mismo.
Napaka-simple ng prinsipyo.
Magdagdag ng isang bagong kahulugan ng macro upang gayahin ang DDX na kasama ng balangkas. At ang kaukulang paraan ng pagtawag.
bSave Ito ang parameter na napunan kapag tumatawag sa DoDataExchange, at ang direksyon ng operasyon ay hinuhusgahan alinsunod dito.
Pagkatapos ay bumalik sa pasadyang klase at magdagdag ng pasadyang mensahe at pagproseso ng mensahe
Susunod, bumalik sa pasadyang klase upang magdagdag ng mga paraan ng pagtanggap at pagproseso ng mensahe

#define WM_WRITE WM_USER + 1 #define WM_HANDLE_POINTER WM_USER + 3 #define WM_READ WM_USER + 2 class FirstCustomItem :public CWindowImpl { public: BEGIN_MSG_MAP(OnInitDialog) MSG_WM_PAINT(OnPaint) MSG_WM_SIZE(OnSize) MESSAGE_HANDLER(WM_READ, notifactionRead) MESSAGE_HANDLER(WM_WRITE, notifactionWrite) END_MSG_MAP()

Magdagdag ng pagtanggap ng mensahe at kaukulang mga pamamaraan sa pagproseso

LRESULT notifactionRead(...) { return readData() } LRESULT notifactionWrite( UINT , LPARAM lparm, WPARAM rparm, BOOL& /*bHandled*/) { writeData(lparm) return 0 } BOOL readData() { CString strL btnL.GetWindowTextA(strL) CString strR btnR.GetWindowTextA(strR) if (strL == '1' && strR == '1') { return TRUE } return FALSE } void writeData(BOOL state) { if (state) { btnL.SetWindowTextA('1') btnR.SetWindowTextA('1') } else { btnL.SetWindowTextA('0') btnR.SetWindowTextA('0') } }

Sa pamamagitan ng paraan, pumunta sa pasadyang kontrol upang magdagdag ng isang kaganapan sa pindutan

LRESULT OnLClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { CString btnStr btnL.GetWindowTextA(btnStr) if (btnStr == '0') { btnL.SetWindowTextA('1') } else { btnL.SetWindowTextA('0') } return 0 } LRESULT OnRClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { CString btnStr btnR.GetWindowTextA(btnStr) if (btnStr == '0') { btnR.SetWindowTextA('1') } else { btnR.SetWindowTextA('0') } return 0 }

Ok, pagkatapos ay maaari kang makipag-ugnay sa pasadyang kontrol na ito at isang halaga ng BOOL sa pamamagitan ng DDX
Dapat mong makita ito. Ang kontrol na ito ay isang kontrol na pinaghalo na may dalawang mga na-click na pindutan at ang halaga ng BOOL na nakuha pagkatapos ng & pagpapatakbo ng numero sa pindutan ng output ng DDX.
Bumalik sa kung saan ito gagamitin Gumamit ng DDX para sa pagbubuklod

BEGIN_DDX_MAP(FirstDialog) DDX_FD_BOOL(IDC_CUSTOM_FIRST,m_SocketState) END_DDX_MAP() BOOL m_SocketState = 1

Magdagdag ng mga kaganapan sa dalawang mga pindutan ng dialog box upang i-reset ang estado at magsagawa ng mga pagpapatakbo ng DDX

LRESULT FirstDialog::OnBnClickedOk(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // TODO: add control notification handler code here m_SocketState = 0 DoDataExchange(TRUE) return 0 } LRESULT FirstDialog::OnBnClickedCancel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { // TODO: add control notification handler code here DoDataExchange(FALSE) if (m_SocketState) { (GetDlgItem(IDC_STATIC)).SetWindowTextA('TRUE') } else { (GetDlgItem(IDC_STATIC)).SetWindowTextA('FALSE') } return 0 }

Tingnan ang ginawa.
DDX