You are on page 1of 96

B GIAO THNG VN TI TRNG I HC HNG HI B MN: KHOA HOC MA Y TI NH KHOA: CNG NGH THNG TIN

BI GING
LP TRNH WINDOWS
TN HC PHN : Lp trnh Windows M HC PHN : 17214 TRNH O TO : I HC CHNH QUY DNG CHO SV NGNH : CNG NGH THNG TIN

HI PHNG - 2010

Bi ging mn hc: L p trinh Windows


Tn hc phn: Lp trnh Windows B mn ph trch ging dy: Khoa hc My tnh Khoa ph trch: CNTT M hc phn: 17214 TS tit L thuyt Thc hnh/Xemina 60 30 30 iu kin tin quyt: T hc 0 Bi tp ln 0 Tng s TC: 3 n mn hc 0 Loi hc phn: 2

Sinh vin phi hc xong cc hc phn sau mi c ng k hc phn ny: L p trinh hng i t ng, C u truc d li u Mc tiu ca hc phn: Cung cp cc kin thc c bn v l p trinh trc quan trn h i u hanh Windows hnh phn cua h iu - Cung c p cac ki n thc v truy c p va can thi p vao cac t hnh Windows Ni dung ch yu Cc kin thc v thao tc vi file v th muc , c s d li u registry , cc lung , ti n trnh, dich vu, cc th vin lin kt ng v lp trnh sockets trn Windows. Ni dung chi tit ca hc phn: TN CHNG MC Chng I. Cc khi nim c bn 1.1. Gii thiu v mi trng l p trinh trn Windows 1.1.1. C s v h i u hanh Windows 1.1.2. Cc phin bn cua h i u hanh Windows 1.1.3. Vai tro cua Windows trn thi trng ph n m m 1.2. Th vi n Win32 v Win64 1.2.1. Win32 API 1.2.2. Win64 API 1.3. Gii thi u v b cng cu Visual Studio 2005 Chng II. H th ng file va th mc 2.1. Truy c p va s du ng h th ng file trn mi trng Windows 2.1.1. H th ng file va th mu c cua Windows 2.1.2. Cc thao tc vi file v th muc trn Windows 2.1.3. Cc vn lin quan ti Unicode 2.2. Cc v du v thao tac vi file 2.2.1. Tao file v x l cc li lin quan PHN PHI S TIT TS LT TH/Xemina 3 0 1 BT 0 KT 0

4 2

4 2

Bi ging mn hc: L p trinh Windows


TN CHNG MC 2.2.2. Copy file 2.2.3. Hi n thi danh sach cac file trong th mu c hi n thi 2.3. Qun l file v th muc nng cao 2.3.1. Con tro file 2.3.2. Truy c p ti cac thu c tinh cua file v th mu c Chng III. H th ng c s d liu Registry 3.1. Khi nim v vai tro cua CSDL Registry 3.1.1. Cc khoa, cc hive 3.1.2. Cc kiu d liu 3.2. Qun l CSDL Registry 3.2.1. Thay i khoa 3.2.2. Thm mi khoa 3.2.3. Li t k cac khoa 3.3. Can thi p Windows qua Registry 3.3.1. Thay i giao di n 3.3.2. Thay i cac thi t l p i vi cac ia 3.3.3. Thay i cac thi t l p vi ngi dung Chng IV. Qun ly cc tin trnh v lung 4.1. Cc tin trnh v lung trn Windows 4.2. Cc thao tc vi tin trnh 4.2.1. Tao tin trnh 4.2.2. K t thuc va thoat khoi m t ti n trinh 4.2.3. Cc thao tc vi bin mi trng cua Windows 4.2.4. V du : Ghi nh t ky thi gian thc hi n cua cc tin trnh 4.3. Qun l lung (thread) trn Windows 4.3.1. Cc khi nim c bn 4.3.2. M hinh Boss /Worker va cac m hinh khc 4.3.3. B nh danh cho lu ng 4.3.4. u tin v cc trang thi cua lung 4.4. M t s vi du v ti n trinh va lu ng 4.4.1. Tm kim song song vi cc tin trnh 4.4.2. Thu t toan s p x p tr n b ng a lu ng Chng V. Cc dich v ca Windows 5.1. T ng quan v dich vu trn Windows 5.2. Cc thnh phn cua mt dich vu 5.2.1. Hm main() 5.2.2. Hm ServiceMain() 5.2.3. Ki m soat dich vu qua cc Handler 5.3. V du: dich vu n gin trn Windows PHN PHI S TIT TS LT TH/Xemina 1 1 BT KT

4 1

6 1

4 2

6 2

1 1

2 1

4 1

6 2

ii

Bi ging mn hc: L p trinh Windows


TN CHNG MC 5.4. Qun l cc dich vu cua Windows 5.4.1. Cc phng php kim sot cc dich vu cua Windows 5.4.2. V du : i u khi n cac dich vu cua Windows Chng VI. L p trinh ma ng vi Sockets 6.1. Khi nim sockets trn Windows 6.2. Cc hm sockets pha server 6.3. Cc hm sockets pha client 6.4. ng dung mang n gian 6.4.1. Pha server 6.4.2. Pha client 6.5. Windows Sockets 2.0 Chng VII. Th vin lin k t ng 7.1. Khi nim v ng dung cua th vin lin k t ng 7.2. H th ng th vi n DLL cua Windows 7.3. Cc bc tao mt th vin DLL 7.3.1. Tao th vi n DLL 7.3.2. Vi t ng du ng go i ti th vi n DLL Nhim v ca sinh vin : PHN PHI S TIT TS LT TH/Xemina 2 2 BT KT

1 4 0,5 0,5 0,5 2 4 1 0,5 0,5 2 0 0

0,5 4 1 1 2

4 0,5 1 2,5

Tham d cc bui thuyt trnh cua gio vin, t hc, t lm bi tp do gio vin giao, tham d cc bi kim tra inh k v cui k. Ti liu hc tp : L Hu a t. Lp trinh Windows. NXB Giao du c. Charles Petzold. Programming Windows, fifth edition. Microsoft Press. 1998.

- Johnson M. Hart. Windows System Programming Third Edition. Addison Wesley Professional. 2004. Hnh thc v tiu chun nh gi sinh vin: Hnh thc thi cui k : Thi vn p. Sinh vin phi m bo cc iu kin theo Quy ch cua Nh trng v cua B

Thang im: Thang im ch A, B, C, D, F im nh gi hc phn: Z = 0,3X + 0,7Y.

iii

Bi ging mn hc: L p trinh Windows


MC LC LI NI U ............................................................................................................................ 1 CHNG 1: CAC KHAI NIM C BN ............................................................................... 2 1. Gii thiu v mi trng lp trnh Windows .................................................................. 2 1.1 C s v h iu hnh Windows ............................................................................ 2 1.2 Cc phin bn cua h iu hnh Windows ............................................................. 2 1.3 Vai tro cua Windows trn thi trng phn mm .................................................... 3 2. Th vin Win32 v Win64 .............................................................................................. 3 2.1 Win32 API .............................................................................................................. 3 2.2 Win64 API .............................................................................................................. 4 3. Cc bc pht trin ng dung trn Windows .................................................................. 4 3.1 Chng trnh Win32 n gin nht. ....................................................................... 4 3.2 Chng trinh ca s n gian ................................................................................. 5 3.3 Qun l cc thng ip ......................................................................................... 14 3.4 Vong lp x l thng ip .................................................................................... 17 Bi tp: .............................................................................................................................. 20 CHNG 2: H THNG FILE VA TH MUC .................................................................... 21 1. Truy c p va s du ng h th ng file trn mi trng Windows ....................................... 21 2. Cc v du v thao tc vi file ......................................................................................... 21 2.1 Serialization .......................................................................................................... 21 2.2 Ci t mt lp Serializable.................................................................................. 24 3. Qun l file v th muc nng cao .................................................................................. 40 Bi tp: .............................................................................................................................. 40 CHNG 3: H THNG CSDL REGISTRY ........................................................................ 41 1. Khi nim v vai tro cua CSDL Registry ...................................................................... 41 1.1 Cc khoa, cc hive ................................................................................................ 41 1.2 Cc kiu d liu .................................................................................................... 42 2. Qun l CSDL Registry ................................................................................................. 43 2.1 Thay i khoa ....................................................................................................... 43 2.2 Thm mi khoa ..................................................................................................... 43 2.3 Li t k cc khoa .................................................................................................... 44 3. Can thi p Windows qua Registry .................................................................................. 44 3.1 Thay i giao di n ................................................................................................ 44 3.2 Thay i cac thi t l p i vi cac ia ................................................................ 44

Bi ging mn hc: L p trinh Windows


3.3 Thay i cac thi t l p vi ngi dung .................................................................. 44 Bi tp: .............................................................................................................................. 44 CHNG 4: QUN LY CAC TIN TRNH V LUNG .................................................... 45 1. Cc tin trnh v lung trn Windows ........................................................................... 45 2. Cc thao tc vi tin trnh ............................................................................................. 46 2.1. Tao tin trnh ........................................................................................................ 46 2.2. K t thuc v thot khoi mt tin trnh ................................................................... 47 2.3. Cc thao tc vi bin mi trng cua Windows .................................................. 47 2.4. V du: Ghi nh t ky thi gian thc hi n cua cac ti n trinh .................................... 47 3. Qun l lung (thread) trn Windows ........................................................................... 49 3.1. Cc khi nim c bn ........................................................................................... 49 3.2. M hinh Boss/Worker va cac m hinh khac ........................................................ 49 3.3. B nh danh cho lu ng ........................................................................................ 49 3.4. u tin v cc trang thi cua lung ................................................................ 50 4. M t s vi du v ti n trinh va lu ng ............................................................................... 50 4.1. Tm kim song song vi cc tin trnh................................................................. 50 4.2. Thu t toan s p x p tr n b ng a lu ng ................................................................ 52 Bi tp: .............................................................................................................................. 55 CHNG 5: CAC DICH VU CUA WINDOWS .................................................................... 56 1. T ng quan v dich vu trn Windows ............................................................................. 56 2. Cc thnh phn cua mt dich vu ................................................................................... 56 2.1 Hm main() ........................................................................................................... 56 2.2 Hm ServiceMain()............................................................................................... 56 2.3 Ki m sot dich vu qua cc Handler ...................................................................... 56 3. V du: dich vu n gin trn Windows .......................................................................... 57 4. Qun l cc dich vu cua Windows ................................................................................ 60 4.1 Cc phng php kim sot cc dich vu cua Windows ........................................ 60 4.2 V du : i u khi n cac dich vu cua Windows ....................................................... 60 Bi tp: .............................................................................................................................. 64 CHNG 6: LP TRINH SOCKET ....................................................................................... 65 1. Khi nim sockets trn Windows .................................................................................. 65 2. Cc hm sockets pha server.......................................................................................... 65 3. Cc hm sockets pha client .......................................................................................... 66 4. ng dung mang n gin .............................................................................................. 66

ii

Bi ging mn hc: L p trinh Windows


4.1 Pha server............................................................................................................. 66 4.2 Pha client ............................................................................................................. 72 5. Windows Sockets 2.0 .................................................................................................... 74 Bi tp: .............................................................................................................................. 74 CHNG 7: TH VIN LIN KT NG ......................................................................... 75 7.1. Khi nim v ng dung cua th vin lin kt ng .................................................... 75 7.2. H thng th vin lin kt ng cua Windows .......................................................... 75 7.3. Cc bc tao mt th vin DLL ................................................................................. 76 7.4. Chia se b nh gia cac th vi n lin k t ng .......................................................... 83 7.5. Cc vn khc v th vin lin kt ng ................................................................. 84 Bi tp: .............................................................................................................................. 85 TI LIU THAM KHO ........................................................................................................ 86 THI THAM KHO ............................................................................................................ 87

iii

Bi ging mn hc: L p trinh Windows


LI NI U H iu hnh Windows cua Microsoft l h iu hnh c ci t nhiu nht trn cc my PC hin nay. S ph bin cua Windows v nn tng phn cng cua Intel dn ti s cn thit phi c nhng hiu bit su v chng, c bit i vi nhng lp trnh vin. Muc ch cua hc phn ny l cung cp cho hc vin mt ci nhn tng quan, t c bn ti chi tit v cc kha canh cua lp trnh trn h iu hnh Windows, t cc chi tit trong cu trc cua mt chng trnh ti cc khi nim cp cao v tin trnh, lung, x l song song, th vin DLL, lp trnh Socket, can thip vo c s d liu Registry .... Ti liu ny da trn nhng kinh nghim v nghin cu m tc gi uc rut, thu thp trong qu trnh ging day mn hc Lp trnh C trn Windows, cung vi s tham kho cua cc ti liu cua cc ng nghip , cc tc gi trong v ngoi nc , t i n trc tuy n Wikipedia . Vi b y chng c chia thnh cc chu khc nhau t cac khai ni m c ban cho ti cc thao tc vi h thng file, th muc, h thng CSDL Registry, qun l tin trnh v lung, lp trnh qun l dich vu, lp trnh socket, th vin lin kt ng DLL hy vng s cung cp cho cc em sinh vin , cc ban c gi mt ti liu b ch . Mc du rt c gng song vn khng trnh khoi mt s thiu sot , hy vng s c cc ban b ng nghip , cc em sinh vin , cc ban c gi gop chn thnh ti co th hon thin hn na ti liu ny. Xin gi li cm n chn thnh ti cc ban b ng nghip v Ban chu nhim khoa Cng ngh Thng tin tao iu kin giup ti liu ny co th hon thnh. Hi phng, thng 06 nm 2010 Tc gi Nguyn Hu Tun

Bi ging mn hc: L p trinh Windows


Chng 1: Cc khi nim c bn Ti liu ny c bin soan cung cp cho ngi ho c nhng kin thc c bn v vic vit cc chng trnh s dung giao din lp trnh API trn mi trng Win32. Ngn ng c s dung l ngn ng C, hu ht cc trnh bin dich C++ hin nay u co th dich c cc chng trnh mu trnh by trong ti liu ny. Hu ht tt c cc thng tin c trnh by trong ti liu ny u co th ng dung cho bt c ngn ng no co th truy cp cc hm API, chng han nh Java, Assembly, v Visual Basic. Ti liu ny c bin soan khng phi day cc ban c gi lp trnh bng ngn ng C, hoc day chung ta s dung bt c mt trnh bin dich cu th no (chng han nh Borland C++, Visual C++, ) tuy nhin trong phn phu luc ti s dnh mt chut cung cp cho cc ban mt s chu v mt s trnh bin dich m ti s dung. 1. Gii thiu v mi trng lp trnh Windows 1.1 C s v h iu hnh Windows H iu hnh Windows l mt h iu hnh dnh cho ngi dung cui (End User Operating System) vi cc tnh nng c bn sau: a nhim, giao din ha, plug and play v quan trng nht l Windows Interface Based - tc l giao din cc chng trnh chay trn Windows u co dang cc ca s. 1.2 Cc phin bn ca h iu hnh Windows Do cch dung ting Anh v vic hiu ting Anh dn ti vic nhiu ngi hiu v cc phin bn cua h iu hnh Windows cha chnh xc. V du co ban cho rng Windows XP Professional Edition v Windows XP Home Edition l hai phin bn khc nhau cua h iu hnh Windows. Thc ra nh vy va ung lai va khng ung, ung l Windows XP Professional Edition v Windows XP Home Edition l hai Edition khc nhau cua cung 1 Version Windows XP, co l sai l v hiu t Edition v Version sai. Version co ngha l mt phin bn, thng i km vi cc s hiu cua phin bn (1.0, 1.2. 5.0) v thng l mt thay i ln i vi bn thn phn mm, v du nh i vi Windows th co 3 thay i ln: thay i v kin truc nn tng cua h iu hnh (tc l phn kernel cua h iu hnh), hai l cp nht cc bn v (patch) cho cc li cua phin bn trc o i vi tt c cc phn cua h iu hnh, ba l cc phn mi cua h iu hnh (co th l cc ng dung i km hoc h tr thm cc cng ngh mi, v du nh i vi Windows l chun Wi-Fi, DVD, dot NET framework hay cc ng dung nh Windows Media Player, IE ). Con Edition l n bn khc nhau cua cung mt phin bn, cc Edition thng gn vi cc yu t v ia l, ngn ng khc nhau (v du nh Compact Edition ngha l bn rut gn, Standard Edition l bn chun, Ultimate Edition l bn co cc tnh nng cao cp nht ). i vi h iu hnh Windows cc Edition khc nhau thng phn bit bi cc tnh nng cua chung, do nhm ti vic phuc vu cc i tng khc nhau nn Microsoft bo i mt s tnh nng khng cn thit v tng thm cc tnh nng m i tng ngi dung hay dung v du nh bn Home Edition nhm ti ngi dung gia nh nn cc tnh nng ha, video, m thanh phi tt, con bn Professional nhm ti cc ngi dung chuyn nghip co trnh cao nn cc tnh nng h thng s cao hn. Windows co cc phin bn sau y: Windows 1.01 Windows 2.03

Bi ging mn hc: L p trinh Windows


Windows 2.11 Windows 3.0 Windows 3.1x Windows For Workgroups 3.1 Windows NT 3.1 Windows For Workgroups 3.11 Windows 3.2 (released in Simplified Chinese only) Windows NT 3.5 Windows NT 3.51 Windows 95 Windows NT 4.0 Windows 98 Windows 98 SE Windows 2000 Windows Me Windows XP Windows XP 64-bit Edition 2003 Windows Server 2003 Windows XP Professional x64 Edition Windows Fundamentals for Legacy PCs Windows Vista Windows Home Server Windows Server 2008 Windows 7 Tt nhin l mi Version trn lai co nhiu Edition khc nhau. Phn nhn (Kernel Core) cua h iu hnh lun l phn quan trng nht cua mt h iu hnh. i vi Windows nhn gm 3 thnh phn: cc dich vu chay mc nhn (kernel-mode service, phn bit vi cc dich vu chay mc ng dung) gm cc th vin chnh cua h iu hnh, cc th vin thc hin qun l tin trnh, lp lich, qun l vo ra d liu trn a cng, b nh. Phn 2 l cc th vin lm vic vi cc phn cng mc chung, phn 3 l cc Diver. 1.3 Vai tr ca Windows trn thi trng phn mm Do s thng tri cua hng Microsoft noi ring v s ph bin gn nh c tn cua h iu hnh Windows noi chung Vit Nam nn Windows ong vai tro ht sc quan trng trong vic pht trin phn mm Vit Nam. V bn cht cc chng trnh u phi thc hin trn mt nn tng (platform) nht inh bao gm cc chi tit t phn cng cho ti phn mm, tuy nhin i vi a s ng dung, cc lp trnh vin cn quan tm nhiu nht ti h iu hnh m ng dung s chay. 2. Th vin Win32 v Win64 2.1 Win32 API Win32 API hay thng c vit tt l Win32 l phin bn 32 bit tng ng vi h iu hnh 32 bit cua Windows. Win32 bao gm cc hm c ci t cua h thng, chng han nh cc hm trong h thng Win16 bit, di dang cc file th vin DLL cua h thng. Li (core) cua Win32 l cc file th vin kernel32.dll, user32.dll v gdi32.dll. Win32 u tin c a ra cng vi h iu hnh Windows NT. Phin bn u tin cua Win32 c pht hnh cung vi h iu hnh Windows 95 (gi l Win32c - compatible), v sau ny ch con l Win32.

Bi ging mn hc: L p trinh Windows


2.2 Win64 API Win64 l phin bn 64 bit cua th vin Win32, l mt bin th dnh cho cc nn tng 64 bit cua h iu hnh Windows (v du hin tai l AMD64 v IA-64). C hai phin bn 32 v 64 bit cua mt ng dung u co th c bin dich t mt m chng trnh chung, mc du co mt s khc bit trong hai phin bn ny. S khc nhau c bn cua hai phin bn l cc con tro ia ch cua Win32 l 32 bit, con vi Win64 l 64 bit. 3. Cc bc pht trin ng dng trn Windows 3.1 Chng trnh Win32 n gin nht. Nu ban l mt ngi mi bt u lp trnh trn mi trng Win32 th thao tc u tin m ban cn phi lm c o l dich mt chng trnh c bn trn mi trng Windows. Hy g oan chng trnh trn vo v nu mi th sun s ban s co mt chng trnh n gin nht (v ngha) trong s cc chng trnh m ban lm. Hy nh l dich chng trnh ny theo kiu dich mt chng trnh vit bng ngn ng C, khng phi ngn ng C++. Trong hu ht cc trng hp iu ny n gin thc hin bng cch i phn tn m rng t cpp thnh c. Chng han ban co th t tn cho file chng trnh sau l test.c v bt u lm vic. #include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK); return 0; } Nu nh chng trnh khng lm vic bc u tin m ban cn lm l c tt c cc li (error) m chng trnh bo ln v nu nh ban khng hiu ngha cua chung hy tra trong bt c mt quyn sch day lp trnh hoc cc sch hng dn i km vi trnh bin dich m ban ang s dung. Hy chc chn l ban co y u cc file m trnh bin dich yu cu. Tht khng may l ti khng th giup nhiu trong trng hp ny v cc li phu thuc vo trnh bin dich v ngi s dung (trong vic gy li cng nh sa li). Ban co th nhn c mt vi cnh bo t trnh bin dich v vic chng trnh khng s dung cc tham s c cung cp cung vi hm WinMain(). Nhng khng sao iu quan trng l ban dich chng trnh thnh cng v co mt chng trnh Win32 thc s. Chung ta s phn tch cc oan m chng trnh k cng hn. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) WinMain() l hm chnh cua mt chng trnh trn mi trng Windows ging nh hm main trn mi trng DOS v UNIX. o l ni cc oan m chng trnh s c thc thi. Cc tham s cua hm main gm co: HINSTANCE hInstance

Bi ging mn hc: L p trinh Windows


Tham s ny qun l module chng trnh (file .exe trong b nh). H iu hnh s dung tham s ny qun l chng trnh khi thc hin. HINSTANCE hPrevInstance Lun l NULL i vi cc chng trnh Win32. LPSTR lpCmdLine Cc tham s dong lnh cua chng trnh c truyn di dang mt xu. Khng bao gm tn chng trnh. int nCmdShow Mt s nguyn co th truyn cho hm ShowWindow(). Chung ta s bn v tham s ny sau. Tham s hInstance c dung cho cc cng vic ai loai nh nap (load) cc ti nguyn v bt c tc vu no khc c thc hin theo kiu tng module c bn. Mt module l mt file EXE hoc file DLL c nap vo chng trnh cua ban. i vi hu ht (khng phi tt c) cc chng trnh c trnh by trong ti liu ny, ch co mt module m chung ta cn quan tm o l file chng trnh (EXE). Cc qui c gi hm WINAPI ch inh qui c gi hm v c inh ngha l _stdcall. Nu nh ban khng hiu ngha cua chung th cng khng cn bn tm nhiu v chung khng nh hng ti ti liu ny ch cn nh l y l mt iu cn thit (kiu cua hm WinMain() l int, nhng kiu gi hm l WINAPI). Cc kiu d liu Win32. Cc ban s thy rng rt nhiu t khoa thng thng hoc cc kiu d liu u co cc cch inh ngha cu th trn mi trng Windows, UINT l unsigned int, LPSTR l char *, vn vn. Vic chn la s dung cch no thc s phu thuc vo ban. Nu ban thch s dung char * hn l LPSTR th hy s dung cch o nhng cn phi kim sot c vic s dung cua mnh (cn nm r cc kiu d liu trc khi thay chung bng mt kiu khc). Ban ch cn nm vng mt s nguyn tc v s hiu ngha cua cc tn ny: LP l long pointer. Trn mi trng Win32 phn long ny khng quan trng v hon ton co th bo qua. Con nu ban khng hiu con tro l g th co l ban nn hc lai v C hoc bo qua chung v tip tuc. Tip n l LPCSTR: long pointer const l mt hng xu, tc l mt xu khng th thay i, ngoi ra gia hai kiu LPSTR v LPCSTR con co th co thm mt ch T nhng nu ban khng co inh s dung cc font Unicode trong chng trnh th no cng chng co ngha g c bit. 3.2 Chng trinh ca s n gian V du: chng trinh g m 1 ca s n gian trn Windows i khi mo i ngi hoi nhau trong khi ho chat vi nhau b ng ph n m m IRC la Lam th nao ta o ra m t ca s ?. Ti e r ng i u nay hoan toan khng phai la m t i u n gin. Khng kho khi ba n bi t minh ang lam gi nhng co kha it nhng i u ba n c n bi t tao ra mt ca s , v nhng iu o hon ton co th gii thch bng mt oan vn bn ngn ho c khoang m t vai phut chat b ng IRC.

Bi ging mn hc: L p trinh Windows


Ti lun mu n lam trc va ho c ky cang sa u vi th y ti se trinh bay oa n ma chng trinh ta o ra m t ca s trc va giai thich sau: #include <windows.h> const char g_szClassName[] = "myWindowClass"; /* tn lp ca s */

// Step 4: the Window Procedure LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: // windows x l cc thng ip con lai return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg;

//Step 1: Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX);

Bi ging mn hc: L p trinh Windows


wc.style = 0; wc.lpfnWndProc = WndProc; /* hm x l thng ip ca s */ wc.cbClsExtra = 0;/* khng cn thng tin thm cho ca s */ wc.cbWndExtra = 0; wc.hInstance wc.hIcon wc.hCursor = hInstance; = LoadIcon(NULL, IDI_APPLICATION); = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /* mu nn */ /*wc.hbrBackground = GetStockObject(WHITE_BRUSH); mu nn trng */ wc.lpszMenuName = NULL; /* khng co h thng thc n */ wc.lpszClassName = g_szClassName; /* tn lp ca s */ wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* ng k lp ca s */ if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

// Step 2: Creating the Window // Tao ra mt th nghim cua lp ca s cho ng dung hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);

if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);

Bi ging mn hc: L p trinh Windows


return 0; } // Hin thi ca s ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);

// Step 3: The Message Loop // Step 3: Tao vong lp x l thng ip while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }

Hnh 1 Ca s cua chng trnh khi chay y co le la m t chng trinh windows n gian nh t ma ba n co th vi t va chc nng cua chng trnh n gin l tao ra mt ca s cng rt n gin . Ban nn g chng trnh v bin dich cha y th va hay am bao la khng co li gi xay ra . Bc 1: ng ky (Registering) lp ca s (Window). M t lp ca s (Window Class) cha cac thng tin v ki u ca s , bao g m thu tu c Window cua no (thu tuc ny kim sot ca s khi no c ta o ra va ap ng la i cac s ki n ngi dung tac ng ln ca s ), cc icon ln v nho cua ca s, v mu nn cua ca s. Theo cch ny ban co th ng k mt lp v sau o tao ra bao nhiu ca s tuy thich ma khng c n chi ro t t ca cac thu c tinh o thm m t l n nao na . H u h t cac thu c tinh ma ba n thi t l p trong lp ca s (window) co th thay i c theo mt cch rt c bn (th m c) n u nh ba n thch. V cn chu l lp ca s ny khng lin quan g ti khi nim cc lp trong C++. const char g_szClassName[] = "myWindowClass"; Bi n trn lu tn cua lp ca s cua chung ta , chung ta s s dung no ng k lp ca s cua chung ta vi h th ng.

Bi ging mn hc: L p trinh Windows


WNDCLASSEX wc; wc.cbSize wc.style = sizeof(WNDCLASSEX); = 0;

wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance wc.hIcon wc.hCursor = hInstance; = LoadIcon(NULL, IDI_APPLICATION); = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } o la oa n ma chng trinh chung ta s du ng trong ham WinMain() ng ky lp ca s cua chung ta . Chung ta s in y u cc thnh vin cua cu truc WNDCLASSEX v gi ti ham RegisterClassEx(). Cc thnh vin cua cu truc nh hng n lp ca s gm co: cbSize: kch thc cua cu truc style: Class Style (CS_*), khng nhm ln vi Window Style (WS_*). Thng thng thu c tinh nay c gan b ng 0. lpfnWndProc: con tro tro ti thu tu c quan ly ca s cho lp ca s nay . cbClsExtra: L ng d li u thm c c p phat trong b nh cho mi ca s thu c loa i ny. Thng thng cung c gan b ng 0. hInstance: Qun l mt th nghim (instance) cua ng dung (tham s u tin cua ham WinMain()). hIcon: Icon ln (th ng la 32x32) hi n thi khi chung ta nhn t hp phm Alt+TAB.

Bi ging mn hc: L p trinh Windows


hCursor: Con tro se xu t hi n khi con tro chu t di chuy n qua vung ca s cua chng trnh. hbrBackground: Tham s s du ng thi t l p m u n n cua ca s . lpszMenuName: tn cua tai nguyn menu c s du ng cho cac ca s cua lp. lpszClassName: Tn inh danh lp ca s hIconSm: Icon nho (16x16) hi n thi trn thanh task bar va goc trn bn trai cua ca s . Ban khng nn lo lng nu cha hiu v cc thuc tnh ny, chung s c gii thch cc phn tip theo cua ti liu ny . M t i u khac c n phai nh la khng nn c nh nhng thu c tinh nay . Ti r t it khi (khng mu n noi la khng bao gi ) nh cac thu c tinh cung nh cc tham s cua cc hm , i u o hoan toan la m t c g ng lang phi thi gian va cng sc . N u nh ba n bi t cac ham ba n c n s du ng trong m t chng trinh nao o , hy tra trong cc ti liu help. N u ba n khng co ca c file help hay down chung v , cc file kiu ny trn mang khng h thi u . Cu i cung thi ba n se bi t cac tham s cua cac ham ma ba n thng xuyn s dung. Ti p n chung ta go i ti ham RegisterClassEx () v kim tra xem hm ny co thnh cng hay khng , n u nh ham tra v sai chung ta se hi n thi m t thng bao th t ba i va dng chng trinh. Bc 2: Tao ra ca s chng trnh Khi a ng ky lp ca s , chung ta co th tao ra cc ca s trong chng trinh . Cc ban nn tra cc tham s cua hm CreateWindowEx () (ban lun nn lm vy khi lm vic vi cc hm API mi), nhng ti se giai thich m t chut y: HWND hwnd; hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); Tham s u tin (WS_EX_CLIENTEDGE) l kiu ca s m rng (extended), trong trng h p ny tham s ny c s dung tao thnh mt ng vin chm bn trong xung quanh ca s . Co th t bng 0 n u chung ta mu n khac . Cng nn thay i cc gi tri khc xem chung lm vic nh th no. Ti p theo chung ta c n co tn lp (g_szClassName), tham s nay bao cho h th ng bi t loai ca s m chung ta mun tao ra . V chung ta mun tao ra mt ca s t lp m chung ta va ng ky nn chung ta s du ng tn cua lp ca s o . Sau o chung ta chi ro tn cua ca s ho c tiu (xu ky t ) s xut hin trong vai tro l tham s Caption hoc Title Bar cua ca s cua chung ta.

10

Bi ging mn hc: L p trinh Windows


Tham s chung ta s du ng WS_OVERLAPPEDWINDOW trong vai tro tham s Window Style. Co kh t cc tham s kiu ny do o ban nn kim tra v thay i gi tri cua chung xem kt qu hat ng nh th no. Chung ta s bn thm v cc tham s ny sau. B n tham s ti p theo (CW_USEDEFAULT, CW_USEDEFAULT, 320, 240) l ta X va Y cua goc trn bn trai cua ca s va cac kich thc dai r ng cua no . Ti a thi t l p gia tri cua X v Y l CW _USEDEFAULT windows t cho n vi tri t ca s chng trinh khi cha y. Hy nh l bn tri cua mn hnh l mt gi tri 0 cua X v no tng dn khi sang phi. inh cua man hinh tng ng vi gia tri 0 cua Y tng dn theo chiu i xung . Cc n vi l cc im nh , l n vi nho nht m mn hnh co th hi n thi c ta i phn giai hi n tai. Ti p theo (NULL, NULL, g_hInst, NULL) chung ta co mt handle qun l ca s cha cua ca s c sinh ra , m t handle quan ly menu , m t handle cho th nghi m cua ng du ng v mt con tro tro ti d li u ca s . Trong windows cac ca s trn man hinh c s p x p theo m t c u truc phn c p theo ki u cac ca s cha va con . Khi chung ta nhin th y m t nut trn m t ca s , nut o l con v no c ch a trong ca s la cha cua no . Trong vi du nay cua chung ta handle cua ca s cha l NULL v chung ta khng co ca s cha no c , y la ca s chinh ho c ca s c p cao nh t cua chung ta . Menu cung la NULL vi chung t a cha co menu chng trnh no . Handle danh cho th nghi m cua chng trinh c gan la gia tri c truy n cho tham s u tin cua ham WinMain (). D liu ca s (th ng la chung ta ch ng bao gi s du ng chung ) co th c s du ng gi cac d li u khac ti ca s ang c ta o ra va cung la NULL. N u ba n ang bn khon v gia tri NULL bi hi m nay thi hay yn tm vi no n gian ch l 0 (zero). Thc s trong C no c inh nghia la ((void*)0) v no c s dung vi cc con tro. V th cho nn ban co th s gp cc cnh bo khi bin dich chng trnh nu s dung NULL cho cac gia tri ki u nguyn , tuy thuc vo trnh bin dich v cp cnh bo c thi t l p vi trinh bin dich. Ban co th bo qua cc cnh bo hoc n gin l s dung gi tri 0 thay th. Nguyn nhn s 1 m mi ngi khng bit tai sao chng trnh cua mnh lai co li l do ho khng ki m tra ca c gia tri tra v cua li go i ham ma ho thc hi n trong chng trinh cua mnh. CreateWindow() s tr v sai trong mt s trng hp ngay c khi ban l mt lp trnh vin co nhiu kinh nghim , ch n gin bi v co rt n hi u li ma chung ta r t d ta o ra chung. Cho ti khi ba n ho c c canh nhanh chong xac inh cac li ki u nh v y , hy t cho mnh mt c hi co th tm ra cc li trong chng trnh , hy lun kim tra cc gi tri tr v khi go i ti cac ham. if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } Sau khi chung ta a ta o ra ca s va ki m tra am bao la chung ta co mt handle hp l , chung ta s hin thi ca s ln mn hnh cua windows (h i u hanh ) b ng cach s du ng

11

Bi ging mn hc: L p trinh Windows


tham s cu i cung cua ham WinMain () v sau o cp nht no m bo l t no c v lai m t cach h p l trn man hinh. ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); Tham s nCmdShow la tuy cho n , ban co th n gin gn no l SW _SHOWNORMAL mi khi chung ta lam vi c vi no.Tuy nhin s du ng tham s c truy n vao h m WinMain() s tao c hi cho cc ngi dung s dung chng trnh cua chung ta co th ch inh h mun ho c khng mu n cua s cua chung ta b t u vi kich thc ca s ln nh t ho c nho nh t Ba n se th y cac tuy chn ny trong cc tham s cua cc shortcut cua ti cc ca s . Bc 3: Vong lp x l thng ip y chinh la trai tim cua toan b chng trinh , h u h t nhng th ma chng trinh cua chung ta x l l nm y. while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; Hm GetMessage () l y m t thng i p t hang i thng i p cua ng du ng cua ba n . B t ky thi i m nao ngi dung di chuy n con chu t , g bn phm , click chu t trn menu cua ca s chng trnh, ho c lam b t c m t thao tac nao a i loa i nh v y , cc thng ip s c sinh ra va thm chung vao hang i thng i p cua chng trnh. B ng cach go i ti ham GetMessage() ban ang yu cu thng ip tip theo loai bo khoi hng i v tr no v cho ban x l . N u nh khng co thng i p nao ham GetMesage () s chuyn sang blocks . N u ban khng quen vi thu t ng, i u o co nghia la no se i cho ti khi co m t thng i p ti p theo x ly (l y v cho chng trinh). TranslateMessage() thc hi n thm m t s x ly trn cac s ki n ban phim ch ng ha n nh sinh ra cac thng i p WM _CHAR cung vi cac thng i p WM _KEYDOWN. Cu i cung DispatchMessage() gi thng i p ti ca s ma thng i p c n c gi ti (x ly theo ki u hng s ki n ). o co th la ca s chinh cua chng trinh ho c co th l mt ca s khc, ho c la m t i u khi n , v trong mt s trng hp l mt ca s c tao ra hu trng bi h th ng ho c m t chng trinh khac . y khng phai la i u ma cac ba n c n phai lo l ng vi t t ca nhng gi chung ta ban ti la l y thng i p va gi no i , h th ng se x ly am bao thng i p o c gi n ung ni se nh n no . Bc 4: Thu tuc ca s. N u nh vong l p thng i p la trai tim cua chng trnh th thu tuc ca s l b no cua chng trnh. y la ni ma t t ca cac thng i p c gi ti ca s cua chung ta c x ly. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

12

Bi ging mn hc: L p trinh Windows


{ switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } Thu tuc ca s c go i ti x ly cac thng i p , tham s HWND la quan ly ca s cua ba n, cng chnh l i tng cua thng ip . i u nay la quan tro ng bi vi ba n co th co hai hoc nhiu hn na cc ca s cung lp va chung se s du ng cung m t thu tu c ca s (WndProc()). S khac nhau y la tham s hwnd se thay i tuy thu c vao ca s la ca s no. Ch ng ha n khi chung ta l y v m t thng i p WM _CLOSE chung ta se huy ca s . V v chung ta s dung handle nhn c qun l ca s qua tham s th nht nn cc ca s khc s khng bi nh hng, ch co ca s nhn thng ip l s bi huy. WM_CLOSE c gi n khi ngi dung nh n chu t vo nut ong ca s hoc nhn t h p phim Alt +F4. Thao tac nay se lam cho ca s bi huy theo m c inh , nhng ti mu n x ly no m t cach dt khoat , v iu ny co th lin quan ti mt s thao tc khc chng han nh ong cac file d li u ang m , ng t cac k t n i c s d li u , cc kt ni mang vn vn trc khi thoat khoi chng trinh. Khi chung ta go i ti ham DestroyWindow () h th ng se gi thng i p WM_DESTROY ti ca s se bi huy bo, trong trng h p nay la ca s cua chung ta , v sau o huy t t ca cac ca s con trc khi loa i bo ca s cua chung ta khoi h th ng . V ch co m t ca s trong chng trinh cua chung ta nn cung khng co nhi u vi c phai lam va chung ta mu n thoat khoi chng trinh , v th hm PostQuitMessage() c go i ti. Hm ny s gi thng i p WM _QUIT ti vong l p thng i p . Chung ta khng bao nhn c thng ip ny v no lm cho hm GetMessage() tr v FALSE , v nh ban s thy trong oan m vong l p x ly thng i p cua chung ta , khi i u o xay ra chung ta dng vi c x ly cac thng i p v tr v gi tri cui cung , tham s wParam cua thng i p WM _QUIT la gia tri c truy n qua ham PostQuitMessage (). Gi tri tr v ch thc s co ch nu chng trnh cua chung ta c thi t k m t chng trinh khac go i va chung ta mu n tra v m t gia tri cu th . Bc 5: khng co bc 5 n y la h t , chung ta khng co bc 5 v ti hy vng cc ban hiu c t nhiu c u truc c ban cua m t chng trinh trn Windows.

13

Bi ging mn hc: L p trinh Windows


3.3 Qun ly cc thng ip V du: window_click. V y la chung ta a co m t ca s , nhng no se khng lam b t c i u gi ngoa i tr nhng gi ma ham DefWindowProc () cho phep no lam , ch ng ha n nh thay i kich thc , phong to, thu nho, vn vn. Qu l khng thu vi t no. Trong ph n ti p theo t i se hng dn cac ba n sa i nhng gi chung ta a vi t ta o ra m t cai gi o mi me. Trc tin c n am bao la ba n a bin dich va cha y chng trinh simple _window thanh cng, chung ta s copy no sang v du mi v sa i ma ngu n (code) cua chng trnh. Chung ta s thm cho chng trnh kh nng hin thi tn cua chng trnh khi ngi dung kch chut vo ca s cua chng trnh . Thc ch t cua kha nng mi nay la chung ta se t x l thng ip nhn chut cua ngi dung, t t nhin la trong ham WndProc(), t: LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } Khi chung ta mu n x ly cac thng i p nh n chu t chung ta c n co t hm cac handle : WM_LBUTTONDOWN (ho c WM _RBUTTONDOWN, WM_MBUTTONDOWN cho cac thao tac nh n chu t phai va gia ): LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_LBUTTONDOWN: // <-

14

Bi ging mn hc: L p trinh Windows


// <break; // <we just added this stuff

case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } Th t x ly cac thng i p la quan tro ng va c n nh la i vi cac thng i p khac (ngoi WM_DESTROY va WM_QUIT) c n co thm cu l nh break sau khi x ly xong thng i p. Trc tin ti se trinh bay oa n ma l nh ma chung ta se thm vao (hi n thi tn cua chng trinh cua chung ta ) v sau o ti s tch hp oan m o vo chng trnh cua chung ta. Trong cac ph n sau cua chng trinh t i se chi cho cac ba n oa n ma va cac ba n t tich h p oa n ma o vao cac chng trinh . i u nay va t t cho ti : ti se khng phai go i go la i cc oan m lnh v va tt cho cc ban : cc ban co c hi thc hn h nhng hi u bi t cua mnh nng cao k nng thc hnh . Con nu nh ban khng chc chn hy tra trong m ngu n chng trinh i kem vi tai li u nay . GetModuleFileName(hInstance, szFileName, MAX_PATH); MessageBox(hwnd, szFileName, MB_ICONINFORMATION); "This program is:", MB_OK |

Hm WndProc() cua chung ta by gi s nh sau: LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_LBUTTONDOWN: // BEGIN NEW CODE { char szFileName[MAX_PATH]; HINSTANCE hInstance = GetModuleHandle(NULL);

15

Bi ging mn hc: L p trinh Windows


GetModuleFileName(hInstance, szFileName, MAX_PATH); MessageBox(hwnd, MB_ICONINFORMATION); } // END NEW CODE break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } Hy chu ti cp du { v } mi. Cc cp du ny l bt buc khi chung ta khai bo cc bi n trong cu l nh switch. Bc tip theo tt nhin l dich chng trnh , chay th v xem kt qu cua chng trnh. Chung ta co th chu l y ti s dung hai bin khi gi hm GetModuleFileName(), tham s th nh t la m t handle tham chi u ti m t chng trinh ang chay, nhng chung ta co th l y handle o u ra ? y mt ln na chung ta lai s dung m t ham API khac GetModuleHandle(), th t may m n la i vi ham nay n u chung ta truy n tham s la NULL vao thi k t qua tra v se la handle tro ti file c s du ng ta o ra ti n trnh gi hm, o chinh xac la cai ma chung ta c n . V do o chung ta co cu lnh: HINSTANCE hInstance = GetModuleHandle(NULL); Tham s th hai khi go i ham GetModuleFileName () l mt con tro xu cha ng dn (k t qua cua ham ) ti chng trinh co handle la tham s th nh t , ki u cua no la LPTRSTR (ho c LPSTR) v do LPSTR hon ton tng t nh char * nn chung ta khao bo m t xu nh sau: char szFileName[MAX_PATH]; MAX_PATH la m t macro thu c windows .h inh nghia dai t i a cua m t xu cha dai ng dn ti m t file trn windows. szFileName, "This program is:", MB_OK |

16

Bi ging mn hc: L p trinh Windows


3.4 Vng lp x ly thng ip Nhng ki n thc v vong lp x l thng ip v cu truc cua vic gi mt thng ip l cn thit vit bt c ng dung no. Cho n thi i m hi n ta i chung ta mi xem xet m t chut v qu trnh x l thng ip , trong ph n nay ti s trnh by vi cc ban k cng hn v c qu trnh x l thng ip. Th nao la m t thng i p? M t thng i p (message) l mt gi tri nguyn (s ). N u ba n tra trong cac file header (y la m t thoi quen t t khi lam vic vi cc hm API) ban s thy cc dong khai bo sau: #define WM_INITDIALOG #define WM_COMMAND 0x0110 0x0111

#define WM_LBUTTONDOWN

0x0201

vn vn . Cc thng ip c s dung tru y n thng h u nh mo i th trn h i u hnh windows t nht l tai cc cp c bn . N u ba n mu n m t ca s ho c m t i u khi n (l mt dang ca s c bit ) thc hi n m t cng vi c nao o , ban s phi gi cho no m t thng i p. N u m t ca s khac mu n ba n lam i u gi o no se gi ti cho ba n m t thng i p. N u m t s ki n xay ra ch ng ha n nh ngi dung go ban phim , di chuy n chu t , nh n chu t ln m t button , th cc thn g i p se c h th ng (h i u hanh windows ) gi n cho cac ca s chiu tac ng cua s ki n o . N u ba n la m t trong cac ca s nh th , ban s ti p nh n va x ly thng i p, co cc hnh vi thch hp. Mi m t thng i p co th co nhi u nh t la hai tham s , wParam va lParam . Nguyn bn wParam l 16 bit va lParam la 32 bit, nhng trn cac h th ng Win 32 chung u l 32 bit. Khng phai t t cac thng i p u s du ng hai tham s nay , v mi thng i p s du ng chung theo cac cach khac nhau . Ch ng ha n thng i p WM _CLOSE khng s du ng ca hai tham s trn, v ban co th bo qua chung . Thng i p WM_COMMAND s du ng ca hai tham s trn , wParam cha hai gia tri , HIWORD(wParam) l thng ip bo hiu (n u thich h p ) v LOWORD(wParam) l inh danh iu khin hoc menu gi thng ip . lParam la HWND (window handle ) cua iu khin gi thng ip hoc NULL nu nh cc thng ip khng phi c gi i t m t i u khi n nao o. HIWORD() v LOWORD l cc macro c inh ngha bi windows ly ra 2 byte cao (High Word) cua mt gi tri 4 byte = 32 bit (0xFFFF0000) v hai byte thp (0x0000FFFF) tng ng. Trn cac h th ng Win 32 m t WORD la m t gia tri 16 bit con DWORD (Double WORD) l mt gi tri 32 bit. gi m t thng i p ba n co th s du ng ham PostMessage () ho c SendMessage (). PostMessage() t (put) thng i p vao hang i thng i p va tra v ngay l p tc. i u o co ngha l mi khi chung ta gi ti hm PostMessage () no s gi thng ip i ngay nhng vic thng i p o co thc hi n ngay hay khng ho c th m chi co thc hi n hay khng thi con cha ch c ch n . Hm SendMessage() gi thng i p trc ti p ti cho ca s nh n thng i p v s khng kt thuc cho ti khi thng ip o c x l xong. N u chung ta mu n ong m t ca s chung ta co th gi ti ca s o m t thng i p WM_CLOSE ch ng ha n nh PostMessage(hwnd, WM_CLOSE, 0, 0); i u nay co tac ng tng t nh vi c chung ta nh n chu t ln bi u t ng trn goc trn bn phai cua ca s . Chu rng wParam v

17

Bi ging mn hc: L p trinh Windows


lParam u b ng 0 trong trng h p nay . i u nay la do nh chung ta a noi trc chung khng co y nghia gi i vi thng i p WM_CLOSE. Cc hp thoai (Dialog). Khi ba n a b t u s du ng cac h p thoa i , ban s cn gi cc thng ip ti cc iu khi n co th truy n thng vi chung . Ban co th lm iu ny bng cch trc ht ly handle quan ly i u khi n b ng ham GetDlgItem () v sau o s dung hm SendMessage () ho c co th s du ng ham SendDlgItemMessage () (hm ny kt h p cng vic cua c hai hm trn). Ban s cung cp cho hm mt handle cua mt ca s v mt ID con v hm s ly handle con cua h p thoa i va gi thng i p ti cho no . SendDlgItemMessage() v mt vi hm API tng t khc ch ng ha n nh GetDlgItemText () s lm vic trn tt c cc ca s ch khng chi vi cac h p thoa i. Th nao la hang i thng i p? Gi s ban ang bn tui bui vi vic x l thng ip WM _PAINT va t nhin ngi dung thc hi n hang loa t thao tac trn ban phim cua may tinh . i u gi se xay ra ? Ban s bi ngt vi c ang ve x ly cac thao tac ban phim cua ngi dung ho c cac thao tac o se bi bo qua? T t ca cac cach giai quy t nh v y u co v n , gii php y l s dung mt hng i lu cac thng ip c n x ly , khi cac thng i p c gi n chung se c thm vao hng i v khi cc thng ip c x l chung s c loai bo kho i hang i . V m bo cc thng ip khng bi bo qua nu nh ban ang bn x l mt thng ip no o , cc thng i p khac se c ch trong hang i cho ti khi ti l t chung c x ly . Th nao la m t vong l p thng i p (vong lp x l thng ip Message Loop) while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } 1. Vong lp thng ip gi ti hm GetMessage (), hm ny s kim tra hng i thng i p cua ba n. N u nh hang i thng i p la rng chng trinh cua ba n v c ban s dng v i cho ti khi co mt thng ip mi (trang thi Block). 2. Khi m t s ki n xay ra lam cho m t thng i p c thm vao hang i (ch ng ha n nh h th ng ghi nh n m t s ki n nh n chu t ) hm GetMessage () s tr v m t gia tri nguyn dng chi ra r ng co m t thng i p c n x ly , v cc thng tin v thng i p o se c i n vao c u truc MSG truy n cho ham . Hm s tr v 0 n u nh thng i p la WM_QUIT va la m t gia tri m n u nh co li xay ra. 3. Chung ta nhn c thng ip (qua bi n Msg ) v truyn cho hm TranslateMessage(), hm ny thc hin x l thm mt chut , dich cc thng tin cua thng i p thanh cac thng i p ky t . Bc nay thc s khng b t bu c nhng m t s thng i p se khng lam vi c c n u khng co bc nay . 4. Sau o chung ta chuy n thng i p cho ham DispatchMessage (). Hm ny s nh n thng i p ki m tra ca s ich cua thng i p va tim ham x ly thng i p

18

Bi ging mn hc: L p trinh Windows


(Window Procedure) cua ca s o. Sau o no se go i ti ham x ly thng i p cua ca s , gi cac tham s : handle cua ca s , thng i p va cac tham s wParam, lParam. 5. Trong ham x ly thng i p ba n se ki m tra thng i p va cac tham s cua no v lm bt c iu g m ban thch vi chung . N u ba n khng mu n x ly cac thng i p m t cach chi ti t cu th, ban hu nh ch vic gi ti hm DefWindowProc (), hm ny s thc hi n cac hanh ng m c inh cho ba n (i u nay thng co nghia la ch ng lam gi ca ). 6. Sau khi ba n a k t thuc vi c x ly thng i p, hm x l thng i p cua ba n tra v , hm DispatchMessage() tr v v chung ta qua tr lai u vong lp. y la m t khai ni m cc ky quan tro ng cua cac chng trinh trn Windows . Thu tuc x ly thng i p cua ba n khng c go i m t c ch thn b bi h thng , m chnh ban gi ti chung m t cach gian ti p thng qua vi c go i ti ham DitpatchMessage (). N u nh ba n mu n, ban co th s dung hm GetWindowLong () trn handle cua ca s ich cua thng i p tm ra thu tuc x l ca s cua no v gi ti hm o mt cch trc tip: while(GetMessage(&Msg, NULL, 0, 0) > 0) { WNDPROC GWL_WNDPROC); fWndProc = (WNDPROC)GetWindowLong(Msg.hwnd,

fWndProc(Msg.hwnd, Msg.message, Msg.wParam, Msg.lParam); } Ti a th cach o vi oa n ma chng trinh trc cua chung ta va no hoa t ng t t , tuy nhin co r t nhi u v n ch ng ha n nh cac chuy n i Unicode /ANSI, cc li gi ti cc iu khin thi gian vn vn m hm ny khng phu hp , v kh nng rt cao l no s break vi h u h t cac chng trinh tr cac chng trinh n gian . V th khng nn th dung hm ny, tr khi ba n chi mu n th no. Chu l chung ta s dung hm Get WindowLong() ly thu tuc x l ca s cua ca s . Tai sao chung ta khng n gin l gi ti hm WndProc () m t cach trc ti p ? Vong lp cc thng ip cua chung ta chiu trch nhim p ng cho tt c cc ca s tron g chng trnh cua chung ta , i u nay bao g m ca cac th ch ng ha n nh cac nut (button) v cc hp danh sach vi cac ham x ly thng i p cua chung , v th chung ta cn m bo l chung ta gi n ung hm x l ca s cua cac thanh ph n o (y thc s la m t vi du cua khai ni m a th trong l p trinh hng i t ng ). V cc ca s co th s dung chung mt hm x l thng i p nn tham s u tin (handle cua ca s ) c dung chi cho ham x ly thng i p bi t ca s nao la danh cho thng i p nao . Nh ba n co th th y ng du ng cua ba n danh ph n ln thi gian cua no cho vong l p x l thng ip , ni ma ba n co th hn hoan gi cac thng i p ti cac ca s se x ly chung . Nhng ba n c n lam gi khi mu n thoat khoi chng trinh ? V chung ta s dung mt vong lp while(), n u nh ham GetMessage () tr v FALSE , vong lp s thot v chung ta s ti cui hm WinMain() v thot khoi chng trnh . o chinh xac la nhng gi ma ham PostQuitMessage() a lam . No t mt thng ip WM _QUIT vao hang i thnmg i p va thay vi tra v m t gia tri dng, hm GetMesage() i n y u cac thng tin cho c u truc Msg v tr v 0. Tai thi im ny thnh vin wParam cua cu truc Msg cha gi tri m ban truy n cho ham PostQuitMessage () v ban cng co th bo qua no , ho c tra v qua ham WinMain(), gi tri o s c dung nh l m thot chng trnh khi tin trnh kt thuc.

19

Bi ging mn hc: L p trinh Windows


Chu : GetMessage() s tr v -1 n u nh g p m t li . Ban cn nh k iu ny nu khng co th chng trinh se g p tru c tr c , m c du ham GetMessage() co ki u BOOL song no vn co th tra v m t gia tri khng phai la TRUE hay FALSE vi BOOL co nghia la UINT (unsigned int). Cc v du sau co v s lm vic tt: while(GetMessage(&Msg, NULL, 0, 0)) while(GetMessage(&Msg, NULL, 0, 0) != 0) while(GetMessage(&Msg, NULL, 0, 0) == TRUE) Thc t t t ca cac trng h p o u sai. Ban co th chu l ti vn s dung trng hp 1 cho t t ca cac vi du cho ti thi i m nay , v nh ti cp no vn lm vic tt khi m hm GetMessage () khng bao gi tra v FALSE . Tuy nhin khng th am bao la ham GetMessage() khng g p li trong t t ca cac trng h p va ba n nn s du ng cach vi t nh sau: while(GetMessage(&Msg, NULL, 0, 0) > 0) Bi tp: Bi tp 1: Vit chng trnh m phong chng trnh my tnh vi cc chc nng tnh ton n gin trn Windows. Bi tp 2: Vit chng trnh vi h thng menu cho php thay i mu nn

20

Bi ging mn hc: L p trinh Windows


Chng 2: H th ng file va th mc 1. Truy c p va s du ng h th ng file trn mi trng Windows H u h t cac ng du ng ngay nay u cho phep ngi dung la cho n ghi la i nhng gi chng trinh a ta o ra . Nhng th c n ghi la i co th la cac tai li u , d li u chng trinh ho c m t thi t l p nao o i vi chng trinh . Trong bai thc hanh nay chung ta se kham pha cac h tr cua Visual C ++ cho vi c cai t cac chc nng nay m t cach d dang . Cu th chung ta s hc: Cch Visual C++ s dung cac lu ng C++ ghi lai d liu trong chng trnh Cch thc s dung file dang nhi phn Cch lm cho cc i tng chng trnh co kh nng serialize Cch thc lu cc bin co kiu khc nhau vo cung mt file 2. Cc vi d v thao tc vi file 2.1 Serialization Co hai phn cua serialization . Khi d li u ng du ng c lu trn ia h th ng di dang mt file th o gi l serialization . Khi tra ng thai cua ng du ng c phu c h i t file o c go i la deserialization . S k t h p cua hai ph n nay lam nn cai go i la serialization cua cc i tng ng dung trong Visual C++. 2.1.1 Cc lp CArchive v CFile Serialization trong cac ng du ng cua Visual C ++ c thc hi n qua lp CArchive. Lp CArchive c thi t k lam vi c vi cac lu ng vao ra cho m t i t ng CFile nh minh ha trong hnh v sau:

Lp nay s du ng cac lu ng cua C ++ cho php cc lung d liu c nap t hoc lu la i thanh cac file m t cach hi u qua . Lp CArchive khng th t n ta i n u khng co m t i t ng CFile g n vi no. Lp CArchive co th cha d li u trong r t nhi u ki u file khac nhau , t t ca chung u l h u du cua lp CFile . Theo m c inh App Wizard se bao goi t t ca cac chc nng ta o v m cc i tng CFile thng thng s dung vi CArchive . N u chung ta mu n ho c

21

Bi ging mn hc: L p trinh Windows


c n thi t phai lam vi c vi m t trong cac lo ai file ny chung ta cn phi vit thm cc oan m chng trnh cn thit co th lm vic vi cc loai file khc nhau. 2.1.2 Hm Serialize Lp CArchive c s du ng trong ham Serialize trn cac i t ng document va d li u trong cac ng du ng Visual C ++. Khi m t ng du ng o c ho c ghi ln m t file ham Serialize cua i t ng document se c go i n , truy n i t ng CArchive c s du ng ghi hoc c t file. Trong ham Serialize th t logic c tun theo xac inh xem o la thao tac o c hay ghi b ng cach go i ti cac ham IsStoring ho c IsLoading . Gi tri tr v t hai hm trn s xc inh xem ng dung cn ghi hay c t lung vo ra cua lp CArchive . M t hm Serialize in hnh s co cu truc nh sau: void CAppDoc::Serialize(CArchive& ar) { // Is the archive being written to? if (ar.IsStoring()) { // Yes, write my variable ar << m_MyVar; } else { // No, read my variable ar >> m_MyVar; } } Chung ta co th t mt hm Serialize trong bt c lp no m chung ta tao ra sau o g n hm Serialize t hm Serialize cua lp document . N u chung ta t cac i t ng do chung ta tao ra vo mt mng cc i t ng ch ng ha n nh CObArray nh trong ng du ng trc y 3 ngy chung ta co th gi ti hm Serialize cua mng t hm Serialize cua lp document. i tng mng s , khi ti l t no , gi ti hm Serialize cua cc i tng c cha bn trong no. 2.1.3 Cc i tng co th Serialize Khi chung ta ta o ra lp CLine trong bai thc hanh s 10 chung ta cn phi thm 2 macro trc khi chung ta co th ghi la i ho c na p d li u t cac file . Hai macro nay , DECLARE_SERIAL va IMPLEMENT _SERIAL se bao goi chc nng c n thi t trong cac lp cua chung ta hm Serialize co th hoat ng ung n. Macro th nh t DECLARE _SERIAL c t ngay dong l nh u tin trong khai bao lp (khi ni m nay gi ng nh khai ni m giao di n cua Java ), no nhn mt tham s l tn cua lp, tc dung cua no l s thm vo lp cua chung ta cc khai bo ton t v hm cn thit chc nng serialization hoa t ng ung n .

22

Bi ging mn hc: L p trinh Windows


V du nh sau: class CMyClass : public CObject { DECLARE_SERIAL (CMyClass) public: virtual void Serialize(CArchive &ar); CMyClass(); virtual ~CMyClass();

}; Macro th hai IMPLEMENTATION _SERIAL c t trong ph n cai t cua lp do chung ta ta o ra . Macro nay c n phai t bn ngoai b t c cac ham thanh vin nao cua lp vi no s thm m cua cc hm cn thit cho lp tng ng vi khai bo cua macro DECLARE_SERIAL. Macro nay nh n 3 tham s . Tham s th nh t l tn lp , gi ng nh macro th nh t . Tham s th hai la tn cua lp c s (l p cha). Tham s th ba la m t s version co th c s du ng xac inh m t file co la ung version thc hi n thao tac o c vi ng du ng cua chung ta hay khng . S version nay phai la m t s dng nn c tng ln mi l n phng thc serializeation cua lp c thay i thay b t c cach thc nao lam thay i d li u c ghi ho c o c t file. V du v khai bo cua macro th hai ny nh sau: // MyClass.cpp: implementation of the CMyClass class.

#include "stdafx.h" #include "MyClass.h"

#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif

IMPLEMENT_SERIAL (CMyClass, CObject, 1) ////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////

23

Bi ging mn hc: L p trinh Windows


CMyClass::CMyClass() { }

CMyClass::~CMyClass() { } 2.1.4 Ci t ham Serialize Cung vi hai macro chung ta cn ci t hm Serialize trong lp cua chung ta . Hm ny nn c khai bao la ham ki u void vi m t tham s (CArchive &ar), ki u public va la ham virtual. Khi cai t ham nay ch ung ta thng s dung cch tip cn ging nh cch tng t c dung trong lp document trn , co ngha l cn phi kim tra o l thao tc ghi hay c trc khi thc hi n thao tac. 2.2 Ci t mt lp Serializable Khi chu ng ta b t u thi t k m t ng du ng mi , m t trong nhng i u u tin ma chung ta cn thit k l cch thc cha d liu trong lp document , d li u ma chng trinh s tao ra v thao tc vi . N u chung ta ta o ra m t ng du ng da ng data -oriented cha m t t p d li u t ngi dung ch ng ha n nh m t ng du ng c s d li u ch ng ha n lam th nao cha cac d li u o trong b nh cua chng trinh . Cch t chc d liu nh th no n u chung ta lm vic vi mt ng dung soan tho vn bn hoc ng dung x l bng tnh ? Khi chung ta a xac inh c cach thi t k cac c u truc d li u ma chng trinh se dung chung ta co th quyt inh c cch t t nh t thc hi n chc nng serialize cho chng trinh va cac lp trong chng trinh . N u chung ta quy t inh lu trc ti p t t ca d li u cua chng trinh trong lp document thi t t ca nhng gi chung ta c n la ghi d li u va o c d li u vi i t ng CArchive trong ham Serialize cua lp document . N u chung ta ta o ra lp ring lu cac d li u cua chng trinh (nh chung ta a lam bai thc hanh s 10) chung ta cn phi thm chc nng se rializable cho cac lp nay chung co th t ghi va o c t file. Trong ng du ng ma chung ta se xy dng bai thc hanh nay chung ta se vi t m t chng trinh c s d li u da ng n gian , flat-file minh ho a cach thc k t h p cac ki u d li u khac nhau trong m t lu ng d li u trong ng du ng serialization . ng dung cua chung ta s hin thi mt s cc trng d liu co kiu khc nhau , ghi va o c d li u t m t lu ng d li u duy nh t vi i t ng CArchive. 2.2.1 Thi t k giao din chng trinh Chung ta co th tao ra cc lp cua ring mnh , cc lp ny co th serialized , co th s dung vi cc ng dung SDI hoc MDI. Noi ngn gn bt c ng dung no lm vic vi bt c ki u d li u nao, du o l mt c s d liu hoc mt ti liu u co th serialized. Chung ta tin hnh cc bc sau: 1. 2. Tao mt project dang SDI co tn l Serialize Trong ph n Document Template String g phn File Extension l fdb

24

Bi ging mn hc: L p trinh Windows


3. 4. CFormView Ph n Advanced features bo d u check ActiveX control Ph n Generated Classes cho n lp c s cua lp CSerialzeView la

5. Nh n Finish , chung ta s nhn c thng bo l chng trnh s khng co chc nng in n, nh n Yes ti p tu c Sau khi ta o m t ng du ng SDI ho c MDI trong o lp view k tha t lp CFormView chung ta cn thit k form view cua chng trnh trnh , qu trnh ny cng ging nh thit k cc hp thoai trong cac ng du ng da ng Dialog based nhng chung ta khng c n co cac nut thot khoi chng trnh hoc huy bo qu trnh thc hin nh trn cc hp thoai thng thng . Vi m t ng du ng SDI ho c MDI chc nng ghi va thoat c a s c t trn cac h th ng menu chng trinh ho c trn cac thanh cng cu . Chu : N u chung ta lam vi c vi cac ng du ng da ng Dialog based App Wizard se khng cung c p cac oa n ma serialization cho ng du ng chung ta c n p hi t thc hin iu ny nu mun. Thi t k form cua chng trinh g m cac i u khi n nh bang sau: Object Static Text Edit Box Static Text Edit Box Static Text Property Setting ID ID ID ID ID IDC_STATIC IDC_ENAME IDC_STATIC IDC_EAGE IDC_STATIC IDC_RSINGLE Checked IDC_RMARRIED IDC_RDIVORCED IDC_RWIDOW IDC_CBEMPLOYED IDC_BFIRST Caption &Name:

Caption &Age

Caption Marital Status: Radio Button ID Group Radio Button ID Radio Button ID Radio Button ID Check Box Button ID ID Caption &Single

Caption &Married Caption &Divorced Caption &Widowed Caption &Employed Caption &First

25

Bi ging mn hc: L p trinh Windows


Button Button Button Static Text ID ID ID ID IDC_BPREV IDC_BNEXT IDC_BLAST IDC_SPOSITION

Caption &Previous Caption Nex&t Caption &Last Caption Record 0 of 0 Giao di n chng trinh sau khi thi t k trong nh sau:

Khi chung ta phat tri n cac ng du ng ho c ca s ki u dialog -based chung ta s gn cc bi n cho cac i u khi n trn ca s cua lp h p thoa i . Tuy nhin i vi m t ng du ng da ng SDI ho c MDI chung ta se g n cho lp nao ? V hm UpdateData l mt hm cua lp CWnd v lp view l mt hu du cua lp CWnd , m c du lp document thi khng phai , nn lp view se la ni logic nh t t cac bi n g n vi cac i u khi n trn ca s chng trinh. gan cac bi n cho cac i u khi n cua chng trinh chung ta m Class Wizard v gn cc bin cho cc iu khin v ch inh lp cha chung l lp view cu th ng dung ny l CSerializeView. Cc bin c gn cho cc iu khin nh sau: Object IDC_EAGE IDC_ENAME IDC_RSINGLE Name m_iAge m_sName Category Type Value Value Value BOOL int CString int

IDC_CBEMPLOYED m_bEmployed

m_iMaritalStatus Value

26

Bi ging mn hc: L p trinh Windows


IDC_SPOSITION m_sPosition Value CString N u nh chung ta ki m tra ma chng trinh cua lp view chung ta se th y r ng khng co hm OnDraw. N u chung ta s du ng lp t tin CFormView cho ng du ng SDI ho c MDI chun g ta khng cn lo lng v hm OnDraw . Thay vao o chung ta se i x vi lp view r t gi ng vi lp h p thoa i nh trong m t ca s hp thoai hoc mt ng dung dang dialog based. S khac nhau chu y u y la d li u chng trinh ma chung ta c n s du ng gan cho cac i u khi n cua ca s chng trinh khng phai la cua lp view ma la cua lp document. Do o chung ta c n xu dng cac tng tac gia cac lp nay truy n cac d li u gia chung. 2.2.2 To lp Serializable Khi chung ta ta o ra m t ng du ng da ng form -based chung ta se gia s r ng chng trinh s cha nhi u ban ghi trong form va ngi dung co th duy t qua cac ban ghi nay thc hi n cac thay i va ghi la i . Ngi dung cung co th thm vao cac ban ghi mi va loa i bo ban ghi nao o . Thch thc i vi chung ta trong vi c xy dng ng du ng la lam th nao bi u din cac ban ghi o co th h tr t t ca cac chc nng cua chng trinh . M t cach ti p c n la ta o ra m t lp bao goi t t ca cac ban ghi va sau o cha t t ca cac bn ghi trong mt mng ging nh cch m chung ta thc hin vi cc ng dung trong ba bi thc hnh trc y . Lp nay se c n k tha t lp CObject va c n cha cac bi n cho t t c cc bin tng ng vi cc iu k hi n c thm vao lp view cung vi phng thc o c v ghi tt c cc bin ny. Cung vi vic thm vo cc phng thc c v ghi cc bin chung ta c n phai lam cho lp nay la m t lp serialiable b ng cac thm vao ham Serialize cho lp cung vi hai macro m t trn. To mt lp c bn Nh cac ba n co th nh t bai thc hanh s 10 khi chung ta mu n ta o ra m t lp mi chung ta cn chn tab Class View v nhn chut phi chn Add | Add Class. Sau o trong h p thoai tip theo chn o l mt Generic class , chung ta s hc nhiu hn v cc lp ny trong bi thc hnh s 16. Ti p theo chung ta go tn lp la CPerson , lp c s cua lp la lp CObject. Sau khi ta o xong lp chung ta ti p tu c thm cac bi n thanh vin cho lp , cc bin thnh vin ny cn phi khp vi cc bin c gn cho cc iu khin trn ca s chng trnh trong lp view nh trong bng sau: Name m_bEmployed m_iAge m_sName m_iMaritalStatus Ci t phng thc c v ghi cho lp CPerson Sau khi a ta o ra lp CPerson chung ta se cung c p m t phng ti n o c va ghi cac bi n cho lp. Cch d nht cung cp cc chc nng ny l thm cc hm inline trong inh ngha cua lp , chung ta co th thm mt tp c c ham inline thi t l p va l y gia tri cua cac Type BOOL int CString int

27

Bi ging mn hc: L p trinh Windows


bi n (ring bi t). V du chung ta co th m file header (Person.h) v sa lai khai bo cua lp CPerson nh sau: class CPerson : public CObject { public: // Functions for setting the variables void SetEmployed(BOOL bEmployed) { m_bEmployed = bEmployed;} void SetMaritalStat(int iStat) { m_iMaritalStatus = iStat;} void SetAge(int iAge) { m_iAge = iAge;} void SetName(CString sName) { m_sName = sName;} // Functions for getting the current settings of the variables BOOL GetEmployed() { return m_bEmployed;} int GetMaritalStatus() { return m_iMaritalStatus;} int GetAge() {return m_iAge;} CString GetName() {return m_sName;} CPerson(); virtual ~CPerson(); private: BOOL m_bEmployed; int m_iMaritalStatus; int m_iAge; CString m_sName; }; Hm cu t mc inh c Visual C++ t ng cung c p va chung ta khng c n sa i (v i Visual 6.0 th vn cn thm hm ny vo). 2.2.3 Ci t hm Serialize Ti p n chung ta se thm ham Serialize cho lp b t u b ng vi c thm 2 macro vao ung vi tri cua chung trong cac file khai bao va cai t cua lp CPerson , sau o thm ham virtual, public Serialize(CArchive &ar) cho lp CPerson nh sau: void CPerson::Serialize(CArchive &ar) { // Call the ancestor function CObject::Serialize(ar);

// Are we writing?

28

Bi ging mn hc: L p trinh Windows


if (ar.IsStoring()) // Write all of the variables, in order ar << m_sName << m_iAge << m_iMaritalStatus << m_bEmployed; else // Read all of the variables, in order ar >> m_sName >> m_iAge >> m_iMaritalStatus >> m_bEmployed; } V ban ch t ham nay cung kha n gian , ban u no go i ti phng thc Serialize cua lp cha xac inh xem o la thao tac o c hay ghi d li u , sau o no go i ti ham IsStoring xc inh nu l ghi d liu th thc hin ghi cc bin thnh vin cua lp con ngc lai th thc hi n thao tac o c (chu th t cua cc bin l quan trng). Chu : chung ta bit l mt ng dung khng phi khi no cng co th c hoc ghi d li u thanh cng nn trn thc t khi chung ta ti n hanh thc hi n ham trn se co m t Exception c throw ki m soat li nhng y chung ta tam thi bo qua vn ny (xem phu lu c A cu n Teach yourself Visual C++ 6.0 in 21 days bi t thm chi ti t ). Ci t cc chc nng cho lp document Khi chung ta xy dng m t ng du ng da ng form -based trong o form n m trn ca s la khng gian chinh ngi dung co th tng tac vi ng du ng co m t gia s khng c c p ro rang la ng du ng cua chung ta se cho phep ngi dung lam vi c vi nhi u ban ghi . i u nay co nghia l chung ta cn h tr cc tnh nng lu v duyt qua cc bn ghi ny . Vi c lu cac ban ghi co th thc hi n d dang b ng cach s du ng m t mang nh chung ta a tng lm trong bi thc hnh s 10. Cch lm ny cho php chung ta co th thm vao m t s l ng bn ghi khng han ch (khng bi t co ung khng na ). Vi c duy t qua cac ban ghi c thc hi n qua b n thao tac la First (duy t ban ghi u tin), Last (bn ghi cui cung), Previous (bn ghi trc) v Next (bn ghi tip theo). Chung ta cn mt chc nng thng bo xc inh bn ghi nao ang c hi n thi . lu tr va h tr cac tinh nng nay lp document c n hai bi n : m t mang va m t chi s ban ghi hi n ta i nh bang sau: Name e m_iCurP osition m_oaPeo ple int Typ

CO bArray

M t vi c khac chung ta c n lam la include file header cua lp CPerson vao file cai t cua lp document (vi tr trc cc file header cua lp document v view) nh sau: #include "stdafx.h" #include "Serialize.h" #include "Person.h"

29

Bi ging mn hc: L p trinh Windows


#include "SerializeDoc.h" #include "SerializeView.h" Thm m t ban ghi mi Trc khi chung ta co th duy t qua cac ban ghi trong chng trinh chung ta c n xy dng chc nng thm m t ban ghi mi cho mang cac i t ng . Cch tip cn tng t nh bi thc hnh s c s dung , v v cc bn ghi mc inh u co cc trng d liu l rng nn chung ta chi c n s du ng ham c u t m c inh do Visual C ++ cung c p la u , ng thi mi khi thm vao m t ban ghi mi chung ta se gan ban ghi hi n ta i la ban ghi mi o (hm ny l private). CPerson* CSerializeDoc::AddNewRecord(void) { // Create a new CPerson object CPerson *pPerson = new CPerson(); try { // Add the new person to the object array m_oaPeople.Add(pPerson); // Mark the document as dirty SetModifiedFlag(); // Set the new position mark m_iCurPosition = (m_oaPeople.GetSize() - 1); } // Did we run into a memory exception? catch (CMemoryException* perr) { // Display a message for the user, giving them the // bad news AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK); // Did we create a line object? if (pPerson) { // Delete it delete pPerson; pPerson = NULL; }

30

Bi ging mn hc: L p trinh Windows


// Delete the exception object perr->Delete(); } return pPerson; } Tng t nh bai thc hanh s 10 chung ta cn cc hm ly tng s bn ghi , s th t b i tng tng ng vi bn ghi hin tai nh sau (cc hm ny l public): int CSerializeDoc::GetTotalRecords(void) { return m_oaPeople.GetCount(); }

int CSerializeDoc::GetCurRecordNbr(void) { return m_iCurPosition + 1; }

CPerson* CSerializeDoc::GetCurRecord(void) { // Are we editing a valid record number? if (m_iCurPosition >= 0) // Yes, return the current record return (CPerson*)m_oaPeople[m_iCurPosition]; else // No, return NULL return NULL; } Cc chc nng tip theo cn c ci t l cc hm cho php thc hin cc thao tc ly cc bn ghi cua mng mt cch tng i ( u, cu i, trc, sau): CPerson* CSerializeDoc::GetFirstRecord(void) { // Are there any records in the array? if (m_oaPeople.GetSize() > 0) {

31

Bi ging mn hc: L p trinh Windows


// Yes, move to position 0 m_iCurPosition = 0; // Return the record in position 0 return (CPerson*)m_oaPeople[0]; }else // No records, return NULL return NULL; }

CPerson* CSerializeDoc::GetNextRecord(void) { // After incrementing the position marker, are we // past the end of the array? if (++m_iCurPosition < m_oaPeople.GetSize()) // No, return the record at the new current position return (CPerson*)m_oaPeople[m_iCurPosition]; else // Yes, add a new record return AddNewRecord(); } CPerson* CSerializeDoc::GetPrevRecord(void) { // Are there any records in the array? if (m_oaPeople.GetSize() > 0) { // Once we decrement the current position, // are we below position 0? if (--m_iCurPosition < 0) // If so, set the record to position 0 m_iCurPosition = 0; // Return the record at the new current position return (CPerson*)m_oaPeople[m_iCurPosition]; }else // No records, return NULL

32

Bi ging mn hc: L p trinh Windows


return NULL; }

CPerson* CSerializeDoc::GetLastRecord(void) { // Are there any records in the array? if (m_oaPeople.GetSize() > 0) { // Move to the last position in the array m_iCurPosition = (m_oaPeople.GetSize() - 1); // Return the record in this position return (CPerson*)m_oaPeople[m_iCurPosition]; }else // No records, return NULL return NULL; } Ti p n la ham Serialize cho mang cac i t ng cua lp document (CSerializeDoc): void CSerializeDoc::Serialize(CArchive& ar) { // Pass the serialization on to the object array m_oaPeople.Serialize(ar); } Hm lm cng tc mi trng, dn dep tt c mi th trc khi bt u mt ti liu mi (hm ny c gi ti khi chng trinh k t thuc ho c trc khi m t tai li u mi c m ): void CSerializeDoc::DeleteContents() { // TODO: Add your specialized code here and/or call the base class // Get the number of lines in the object array int liCount = m_oaPeople.GetSize(); int liPos;

// Are there any objects in the array? if (liCount) {

33

Bi ging mn hc: L p trinh Windows


// Loop through the array, deleting each object for (liPos = 0; liPos < liCount; liPos++) delete m_oaPeople[liPos]; // Reset the array m_oaPeople.RemoveAll(); } CDocument::DeleteContents(); } Chung ta co th thy cc bc thc hin hon ton ging vi bi thc hnh s 10, v cng cn nhc lai mt chu o l : c n phai chuy n i t ng l y t mang CObArray thanh ki u CPerson vi o la m t bi n ki u CObject. Ti p theo c n phai sa la i ham tng ng vi s ki n OnNewDocument: BOOL CSerializeDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE;

// TODO: add reinitialization code here // (SDI documents will reuse this document) // If unable to add a new record, return FALSE if (!AddNewRecord()) return FALSE;

// Get a pointer to the view POSITION pos = GetFirstViewPosition(); CSerializeView* pView = (CSerializeView*)GetNextView(pos); // Tell the view that it's got a new data set if (pView) pView->NewDataSet(); return TRUE; } Khi m t tai li u mi b t u chng trinh se a ra m t form rng sn sang nh p thng tin mi , v bn ghi ny co th sn sng nhn thng tin chung ta thm vao m t ban ghi trong mang cac i t ng va khi m t ban ghi mi c thm vao mang chung ta c n thay i vi c hi n thi chi ra r ng ban ghi mi o t n ta i ng c la i cac hi n thi se ti p tu c vi ba n

34

Bi ging mn hc: L p trinh Windows


ghi cu i cung t t p ban ghi trc (v ngi dung co th bn khon tai sao ng dung cua chung ta khng bt u vi mt tp bn ghi mi). Khi m m t t p d li u sn co chung ta khng c n thm vao b t c ban ghi mi na o nhng vn c n phai cho i t ng view bi t r ng no c n phai lam ti ban ghi c hi n thi cho ngi dung . Do o chung ta co th thm oa n ma tng t cho ham OnOpenDocument nh sau (bo phn u co chc nng thm vo mt bn ghi mi) nh sau: BOOL CSerializeDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE;

// TODO: Add your specialized creation code here // Get a pointer to the view POSITION pos = GetFirstViewPosition(); CSerializeView* pView = (CSerializeView*)GetNextView(pos); // Tell the view that it's got a new data set if (pView) pView->NewDataSet();

return TRUE; } o la t t ca cac cng vi c chu n bi , t chc va x ly d li u cua lp document, ti p n chung ta s lm vic vi lp view tng tc vi ngi dung. i u u tin c n chu y la cac include trong cac file ma ngu n c n theo ung th t (gi ng bai thc hanh s 10): lp CPerson t rc, sau o ti lp document va cu i cung la lp view va cac chi thi include nay chi thc hi n trong cac file cai t lp (khc vi C/C++ thng thng) #include "stdafx.h" #include "Serialize.h"

#include "Person.h" #include "SerializeDoc.h" #include "SerializeView.h" V s lng cc thao tc i vi cc bn ghi l kh nhiu nn cng ging nh bi thc hnh 10 (s du ng 1 bi n lu i m hi n ta i cua con tro chu t ) trong bai thc hanh nay cho ti n chung ta thm m t bi n thanh vin ki u CPerson * co tn l m_pCurPerson cho lp View.

35

Bi ging mn hc: L p trinh Windows


Hm u tin m chung ta s thc hin l hm hin thi d liu , nhng chc nng nay c s du ng trong h u h t cac tng tac nn chung ta se l m mt hm ring sau o gi n hm ny (gi ng ham Draw cua lp CLine trong bai thc hanh 10 v chc nng ) ( hm private): void CSerializeView::PopulateView(void) { // Get a pointer to the current document CSerializeDoc* pDoc = GetDocument(); if (pDoc) { // Display the current record position in the set m_sPosition.Format("Record %d of %d", pDoc->GetCurRecordNbr(), pDoc->GetTotalRecords()); } // Do we have a valid record object? if (m_pCurPerson) { // Yes, get all of the record values m_bEmployed = m_pCurPerson->GetEmployed(); m_iAge = m_pCurPerson->GetAge(); m_sName = m_pCurPerson->GetName(); m_iMaritalStatus = m_pCurPerson->GetMaritalStatus(); } // Update the display UpdateData(FALSE); } Ti p n la cc hm duyt qua cc bn ghi , ng thi cung la cac ham x ly cac s ki n tng ng vi cac nut l nh: void CSerializeView::OnBnClickedBfirst() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) {

36

Bi ging mn hc: L p trinh Windows


// Get the first record from the document m_pCurPerson = pDoc->GetFirstRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } }

void CSerializeView::OnBnClickedBlast() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) { // Get the last record from the document m_pCurPerson = pDoc->GetLastRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } } void CSerializeView::OnBnClickedBprev() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) {

37

Bi ging mn hc: L p trinh Windows


// Get the last record from the document m_pCurPerson = pDoc->GetPrevRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } }

void CSerializeView::OnBnClickedBnext() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) { // Get the last record from the document m_pCurPerson = pDoc->GetNextRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } } Ti p n chung ta c n m t ham reset la i lp view mi khi m t ban ghi mi c b t u ho c c m ngi khng ti p tu c nhin th y t p ban ghi cu . Chung ta co th gi ti hm x ly s ki n cua nut First bu c lp view a ra ban ghi u tin trong t p ban ghi . lam i u nay chung ta thm m t ham void (pubic) tn la NewDataSet nh sau: void CSerializeView::NewDataSet(void) { OnBnClickedBfirst(); }

38

Bi ging mn hc: L p trinh Windows


n y chung ta co th dich va cha y chng trinh nhng cac ba n se th y chi cac cac nut duyt qua cc bn ghi l co tc dung con cc iu khin khc cua form l khng co tc dung g. i u na y la do chung ta cha co cac ham x ly cac i u khi n trn form . C n thm cc hm x l cc s kin vi cc iu khin trn form chng trnh nh sau: Hm x l du check Employed: void CSerializeView::OnBnClickedCbemployed() { // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetEmployed(m_bEmployed); } hm x l cc s kin cho cc nut Radio: void CSerializeView::OnBnClickedMaritalstatus() { // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetMaritalStat(m_iMaritalStatus); } i vi cc trng tn v tui chung ta cn x l s kin EN _CHANGE va go i ti cac hm SetName, SetAge tng ng cua lp CPerson nh sau: void CSerializeView::OnEnChangeEname() { // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetName(m_sName); }

void CSerializeView::OnEnChangeEage() {

39

Bi ging mn hc: L p trinh Windows


// TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetAge(m_iAge); } Hy dich chay th v nhp d liu vo thy cc chc nng cua chng trnh chay ung (y qua la m t bai thc hanh khng d dang). 3. Qun ly file v th mc nng cao Bi tp: Bi tp 1: Vit chng trnh m phong tm kim file. Bi tp 2: Vit chng trnh lit k tt c cc thng tin v cc file v th muc trong mt th muc.

40

Bi ging mn hc: L p trinh Windows


Chng 3: H th ng CSDL Registry 1. Khi nim v vai tr ca CSDL Registry 1.1 Cc khoa, cc hive Registry l ni lu tr tt c cc cc loai cu truc d liu. Cu hnh h thng Windows, cu hnh phn cng my tnh, cu hnh thng tin v cc chng trnh ng dung da trn Win32, v cc thit lp ngi dung khc u c lu trong Registry.

V du, bt c mt phn cng my tnh no thay i u lm chc nng Plug and Play (Cm v chay) khi tao ngay v lm thay i lun cu hnh trong Registry. Registry lu tr tt c cc thit lp v cu truc b nh, phn cng, thit bi ngoai vi, v cc thnh phn lin quan n mang. Ban s tm thy o nhiu hn nhng thit lp cn thit trong cc tp khi tao ban u T Win98 v sau, Windows co s dung Registry Checker t qut Registry, nu khng thy g, no t lu backup mt ln trong ngy, nu tm thy li s sa... co th sa bng cch thay th bn Registry backup gn nht con tt. Registry Checker ti u ho v nn file backup thnh cng mi ln khi ng my. No con lm mt loat cc vic linh tinh nh loai bo nhng khong trng khng dung trong Registry, ti u ho...

41

Bi ging mn hc: L p trinh Windows

Cc tp Registry cua Windows. Registry hin tai bao gm 3 tp chnh: 1. Tp USER.DAT Dung lu tr nhng xc lp ngi s dung i vi cc phn mm. 2. Tp SYSTEM.DAT Dung lu tr nhng xc lp lin quan ti my tnh v phn cng. 3. Tp Policy.pol System policies c thit k chun bi cho vic ghi bt c thit lp c cha trong 2 thnh phn registry khc nhau. System policies co th cha d liu b sung c trng ti mang hay mi trng t hp nh c ci t bi network administrator. Bn thn System policies cng c cha trong tp Policy.pol. Khng nh SYSTEM.DAT v USER.DAT, Policy.pol khng phi l thnh phn bt buc cua phn ci t Windows. Cc khoa chnh trong mt CSDL Registry: + HKEY_LOCAL_MACHINE cha cc thng tin v cu hnh vt l cua h thng cung vi cc phn mm c ci t trn h thng. + HKEY_USERS: cha cc thng tin cu hnh cua ti khon ngi dung + HKEY_CURRENT_CONFIG: cha cc thng tin thit lp cua h thng hin tai chng han nh phn gii mn hnh hay font ch. + HKEY_CLASS_ROOT: cha cc thng tin nh xa t cc kiu file sang cc ng dung m chung. HKEY_CURRENT_USER: cha cc thng tin v cc ti khon trn h thng, chng han nh cc bin mi trng, cc my in v cc tuy chn ng dung khc. 1.2 Cc kiu d liu Li khuyn ca Microsoft v nhng cng c x ly registry

42

Bi ging mn hc: L p trinh Windows


Phng php Control Panel System Policy Editor Cc chng trnh tin ch th 3 Thit lp Phn ln thit lp h thng SYSTEM. V du ban s dung Display Properties sa cc thnh phn cua muc appearance Thit lp ngi dung, vi thit lp h thng. Thit lp chi tit ng dung

Ban co th s dung Registry Editor thay i Registry bng tay. Ti thng dung Norton Registry Editor v no con co thm chc nng khc, v du nh tm v thay th i vi cc thnh phn cua Registry. T cc phn mm Registry Editor trn, ta nhn thy registry c b tr thnh cc nhnh ln. Tai mi nhnh co cc kho SUBKEY. Tai cc SUBKEY d liu c lu cc dang: 1. String (Dang chui) 2. Numeric (Dang s) 3. Binary (Dang nhi phn) 4. Expanded String (Dang chui m rng) 5. MultiString (Dang chui tng hp) (Nu ban dung Registry Editor - REGEDIT. EXE th s gi tn khc l DWORD) 2. Qun ly CSDL Registry Khi lp trnh i vi Registry, ban phi thc hin ht sc thn trng, sao lu cc tp ny thng xuyn trnh li ng tic, phi mt cng ci lai th cng rt mt thi gian.S dung cc hm API i vi Registry cng xin ht sc thn trng. 2.1 Thay i khoa thay i gi tri cua mt khoa trong CSDL Registry chung ta s dung hm LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD reserved, DWORD dwType, CONST BYTE * lpData, CONST cbData). 2.2 Thm mi khoa lm vic vi cc khoa trong CSDL Registry u tin chung ta s quan tm ti cc hm thm khoa mi: LONG RegOpenKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult). Trong o tham s th nht l handle tro ti khoa ang m, tham s phkResult tro ti mt bin co kiu HKEY cho khoa co th m mi, lpSubKey l tn cua subkey m chung ta mun m, thng thng co th l mt ng dn chng han nh Microsoft\WindowsNT\CurrentVersion. Gi tri NULL cho bin ny co ngha l mt khoa bng gi tri hKey s c sinh ra. Bin ulOptions l bin d tr v co gi tri bng 0. Bin samDesired l mt na truy cp m t gi tri bo mt cho khoa mi, co th l kt hp cua cc gi tri hng s KEY_ALL_ACCESS, KEY_WRITE, KEY_QUERY_VALUE, KEY_ENUMERATE_SUBKEYS. Gi tri tr v cua hm thng l ERROR_SUCCESS. Cng co th dung hm LONG RegCreateKeyEx( HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, PSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition) tao khoa mi.

43

Bi ging mn hc: L p trinh Windows


2.3 Lit k cac khoa Hm lit k cc khoa trong CSDL Registry l hm LONG RegEnumKeyEx(HKEY hKey, DWORD dwIndex, LPTSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPTSTR lpClass, LPDWORD lpcbClass, PFILETIME lpftLastWriteTime). 3. Can thip Windows qua Registry Hu nh tt c cc thay i, thit lp cua Windows u co th c thc hin thng qua vic thit lp cc gi tri trong CSDL Registry, vn ct li l chung ta cn nm c khoa v gi tri cn thay i tng ng. 3.1 Thay i giao din ngn cm khng cho ngi dung thay i Wallpaper chung ta co th thay i gi tri khoa:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/policies/ActiveDeskto p vi gi tri DWORD l 1. ch inh file Wallpaper cua Windows ta co th sa cc khoa HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\ System vi cc khoa l Wallpaper, WallpaperStyle v gi tri kiu REG_SZ (String) l ng dn ti file nh. 3.2 Thay i cac thi t l p i vi cac ia thay i thit lp vi cc a ta thc hin vi cc khoa HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices co tn l MountedDevices nh hnh sau:

3.3 Thay i cac thi t l p vi ngi dung Cc bin mi trng cua mt ngi dung nm trong phn HKEY_CURRENT_USER\Environment, con cho c h thng nm trong phn HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. Bi tp: Bi tp 1: Vit chng trnh thay i giao din Windows bng cch s dung can thip qua Registry. Bi tp 2: Vit chng trnh thay i cc bin mi trng cua Windows bng cch s dung can thip qua Registry.

44

Bi ging mn hc: L p trinh Windows


Chng 4: Qun ly cc ti n trinh va lu ng 1. Cc tin trnh v lung trn Windows Tt c cc tin trnh (process) cua Windows u co mt hoc nhiu lung (thread) v lung chnh l n vi thc thi c s nht cua Windows. Cc lung c lp lich da trn cc nhn t: s sn sng cua cc ti nguyn nh CPU v b nh vt l, u tin. Windows h tr kin truc a x l i xng SMP (Symmetric MultiProcessing) bt u t phin bn NT4, do o cc lung co th chay trn cac CPU ring r trong cung mt h thng. Trn quan im cua lp trnh vin mi tin trnh s bao gm cc ti nguyn: + Mt hoc nhiu lung + Mt khng gian b nh o ring. + Mt hoc nhiu oan m, bao gm cua cc oan m trong cc file DLL. + Mt hoc nhiu phn oan d liu cha cc d liu ton cuc. + Cc gi tri bin mi trng + Vung nh Heap + Cc ti nguyn khc chng han nh cc handle v cc heap m sn. Mi lung trong mt tin trnh s chia s m chng trnh, cc bin ton cuc, cc bin mi trng, cc ti nguyn. Mi lung s c lp lich mt cch ring r v co cc thnh phn sau: + Mt ngn xp cc li gi ti cc thu tuc, cc ngt, cc qun l bit l, v b nh + Mt mng TLS (Threa Local Storage) cc con tro co th cp pht b nh lu tr d liu cho lung. + Mt tham s trn stack, t luc bt u tao ra lung, c s dung ring cho mi lung. + Mt cu truc ng cnh, c qun l bi nhn.

45

Bi ging mn hc: L p trinh Windows

2. Cc thao tc vi tin trnh 2.1. To tin trnh Hm c bn qun l cc tin trnh cua Windows l hm CreateProcess(), hm ny tao ra mt tin trnh vi mt lung n. Tham s m hm cn l tn file chng trnh s thc hin. Chung ta co th thy co nhiu cp ti khi nim tin trnh cha, tin trnh con nhng thc s th quan h ny khng c qun l bi Windows. Windows n thun ch tham chiu ti cc tin trnh tai ra mt tin trnh con m no l tin trnh cha. Hm CreateProcess() co 10 tham s: BOOL CreateProcess ( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpsaProcess, LPSECURITY_ATTRIBUTES lpsaThread, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,

46

Bi ging mn hc: L p trinh Windows


LPCTSTR lpCurDir, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcInfo) 2.2. K t thuc va thoat khoi m t ti n trinh Sau khi tin trnh kt thuc, tin trnh, hay chnh xc hn l mt lung chay trong tin trnh s gi ti hm ExitProcess() kt thuc tin trnh. Hm ny khng tr v gi tri m thay vo o s kt thuc tt c cc lung cua tin trnh. Hm co th gi ti ly m kt thuc mt tin trnh l GetExitCodeProcess(). 2.3. Cc thao tc vi bin mi trng ca Windows thao tc vi cc bin mi trng cua Windows ta dung hai hm sau: DWORD GetEnvironmentVariable ( LPCTSTR lpName, LPTSTR lpValue, DWORD cchValue) BOOL SetEnvironmentVariable ( LPCTSTR lpName, LPCTSTR lpValue) 2.4. Vi d: Ghi nh t ky thi gian th c hin cua cac ti n trinh #include "EvryThng.h" int _tmain (int argc, LPTSTR argv []) { STARTUPINFO StartUp; PROCESS_INFORMATION ProcInfo; union { /* Structure required for file time arithmetic. */ LONGLONG li; FILETIME ft; } CreateTime, ExitTime, ElapsedTime; FILETIME KernelTime, UserTime; SYSTEMTIME ElTiSys, KeTiSys, UsTiSys, StartTimeSys, ExitTimeSys; LPTSTR targv = SkipArg (GetCommandLine ()); OSVERSIONINFO OSVer; BOOL IsNT; HANDLE hProc;

OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

47

Bi ging mn hc: L p trinh Windows


GetVersionEx (&OSVer); IsNT = (OSVer.dwPlatformId == VER_PLATFORM_WIN32_NT); /* NT (all versions) returns VER_PLATFORM_WIN32_NT. */ GetStartupInfo (&StartUp); GetSystemTime (&StartTimeSys);

/* Execute the command line; wait for process to complete. */ CreateProcess (NULL, targv, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartUp, &ProcInfo);

/* Assure that we have all REQUIRED access to the process. */ DuplicateHandle (GetCurrentProcess (), ProcInfo.hProcess, GetCurrentProcess (), &hProc, PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, 0); WaitForSingleObject (hProc, INFINITE); GetSystemTime (&ExitTimeSys);

if (IsNT) { /* W NT. Elapsed, Kernel, & User times. */ GetProcessTimes (hProc, &CreateTime.ft, &ExitTime.ft, &KernelTime, &UserTime); ElapsedTime.li = ExitTime.li - CreateTime.li; FileTimeToSystemTime (&ElapsedTime.ft, &ElTiSys); FileTimeToSystemTime (&KernelTime, &KeTiSys); FileTimeToSystemTime (&UserTime, &UsTiSys); _tprintf (_T ("Real Time: %02d:%02d:%02d:%03d\n"), ElTiSys.wHour, ElTiSys.wMinute, ElTiSys.wSecond, ElTiSys.wMilliseconds); _tprintf (_T ("User Time: %02d:%02d:%02d:%03d\n"), UsTiSys.wHour, UsTiSys.wMinute, UsTiSys.wSecond, UsTiSys.wMilliseconds); _tprintf (_T ("Sys Time: %02d:%02d:%02d:%03d\n"), KeTiSys.wHour, KeTiSys.wMinute, KeTiSys.wSecond, KeTiSys.wMilliseconds); } else {

48

Bi ging mn hc: L p trinh Windows


/* Windows 9x and CE. Elapsed time only. */ ... } CloseHandle (ProcInfo.hThread); CloseHandle (ProcInfo.hProcess); CloseHandle (hProc); return 0; } 3. Qun ly lung (thread) trn Windows 3.1. Cc khi nim c bn Trong phn trc chung ta xem xt cch thc mt lung thc hin kt thuc mt tin trnh. Cc lung trong mt tin trnh chia s chung d liu v m lnh, v th v bn cht cc lung o cng co vung nh ring cua chung. Windows p ng iu ny bng mt s cch sau: + Mi lung co mt stack cua ring no cho cc li gi hm v cc x l khc + Li gi tin trnh co th truyn mt bin, con tro, ti thi gian tao ra lung. + Mi lung co th cp pht TLS cua ring no. 3.2. M hinh Boss/Worker va cac m hinh khac Lnh grepMT minh ha cho m hnh Boss/Worker. Lung boss (lung chnh) s gn cc tc vu cho lung worker thc hin. Mi lung worker s c cho mt file tm kim v worker s tr v gi tri cua no cho boss thread. Xem thm v du sp xp trn hiu r m hnh ny. 3.3. B nh danh cho lu ng Cc lung co th cn phi cp pht v qun l b nh cua ring no v bo v cc vung nh o khoi cc lung khc. iu ny c thc hin qua cc TLS, co th minh ha bng hnh v sau:

49

Bi ging mn hc: L p trinh Windows


3.4. u tin v cc trng thi ca lung Cc lung thuc v nhn cua Windows lun co u tin cao nht khi sn sng thc hin. Mt lung c coi l khng sn sng thc hin nu no trang thi ch, treo, hay bi block bi mt l do no o. 4. M t s vi du v ti n trinh va lu ng 4.1. Tm kim song song vi cc tin trnh #include "EvryThng.h" int _tmain (DWORD argc, LPTSTR argv []) /* Create a separate process to search each file on the command line. Each process is given a temporary file, in the current directory, to receive the results. */ { HANDLE hTempFile; SECURITY_ATTRIBUTES StdOutSA = /* SA for inheritable handle. */ {sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; TCHAR CommandLine [MAX_PATH + 100]; STARTUPINFO StartUpSearch, StartUp; PROCESS_INFORMATION ProcessInfo; DWORD iProc, ExCode; HANDLE *hProc; /* Pointer to an array of proc handles. */ typedef struct {TCHAR TempFile [MAX_PATH];} PROCFILE; PROCFILE *ProcFile; /* Pointer to array of temp file names. */ GetStartupInfo (&StartUpSearch); GetStartupInfo (&StartUp); ProcFile = malloc ((argc - 2) * sizeof (PROCFILE)); hProc = malloc ((argc - 2) * sizeof (HANDLE));

/* Create a separate "grep" process for each file. */ for (iProc = 0; iProc < argc - 2; iProc++) { _stprintf (CommandLine, _T ("%s%s %s"), _T ("grep "), argv [1], argv [iProc + 2]); GetTempFileName (_T ("."), _T ("gtm"), 0, ProcFile [iProc].TempFile); /* For search results. */ hTempFile = /* This handle is inheritable */

50

Bi ging mn hc: L p trinh Windows


CreateFile (ProcFile [iProc].TempFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &StdOutSA, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); StartUpSearch.dwFlags = STARTF_USESTDHANDLES; StartUpSearch.hStdOutput = hTempFile; StartUpSearch.hStdError = hTempFile; StartUpSearch.hStdInput = GetStdHandle (STD_INPUT_HANDLE);

/* Create a process to execute the command line. */ CreateProcess (NULL, CommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartUpSearch, &ProcessInfo); /* Close unwanted handles. */ CloseHandle (hTempFile); CloseHandle (ProcessInfo.hThread); hProc [iProc] = ProcessInfo.hProcess; }

/* Processes are all running. Wait for them to complete. */ for (iProc = 0; iProc < argc - 2; iProc += MAXIMUM_WAIT_OBJECTS) WaitForMultipleObjects ( /* Allows a large # of processes */ min (MAXIMUM_WAIT_OBJECTS, argc - 2 - iProc), &hProc [iProc], TRUE, INFINITE); /* Result files sent to std output using "cat." */ for (iProc = 0; iProc < argc - 2; iProc++) { if (GetExitCodeProcess(hProc [iProc], &ExCode) && ExCode==0) { /* Pattern was detected -- List results. */ if (argc > 3) _tprintf (_T ("%s:\n"), argv [iProc + 2]); fflush (stdout); /* Multiple processes use stdout. */ _stprintf (CommandLine, _T ("%s%s"), _T ("cat "), ProcFile [iProc].TempFile); CreateProcess (NULL, CommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartUp, &ProcessInfo); WaitForSingleObject (ProcessInfo.hProcess, INFINITE); CloseHandle (ProcessInfo.hProcess);

51

Bi ging mn hc: L p trinh Windows


CloseHandle (ProcessInfo.hThread); } CloseHandle (hProc [iProc]); DeleteFile (ProcFile [iProc].TempFile); } free (ProcFile); free (hProc); return 0; } 4.2. Thu t toan s p x p tr n b ng a lu ng #include "EvryThng.h" #define DATALEN 56 /* Key: 8 bytes; Data: 56 bytes. */ #define KEYLEN 8 typedef struct _RECORD { CHAR Key [KEYLEN]; TCHAR Data [DATALEN]; } RECORD; #define RECSIZE sizeof (RECORD) typedef RECORD * LPRECORD;

typedef struct _THREADARG { DWORD iTh; LPRECORD LowRec; LPRECORD HighRec;

/* Thread argument */

/* Thread number: 0, 1, 2, ... */ /* Low record */ /* High record */

} THREADARG, *PTHREADARG;

static int KeyCompare (LPCTSTR, LPCTSTR); static DWORD WINAPI ThSort (PTHREADARG pThArg); static DWORD nRec; /* Total number of records to be sorted. */ static HANDLE * ThreadHandle;

int _tmain (int argc, LPTSTR argv []) { HANDLE hFile; LPRECORD pRecords = NULL;

52

Bi ging mn hc: L p trinh Windows


DWORD FsLow, nRead, LowRecNo, nRecTh, NPr, ThId, iTh; BOOL NoPrint; int iFF, iNP; PTHREADARG ThArg; LPTSTR StringEnd;

iNP = Options (argc, argv, _T ("n"), &NoPrint, NULL); iFF = iNP + 1; NPr = _ttoi (argv [iNP]); /* Number of threads. */ hFile = CreateFile (argv [iFF], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); FsLow = GetFileSize (hFile, NULL); nRec = FsLow / RECSIZE; /* Total number of records. */ nRecTh = nRec / NPr; /* Records per thread. */

/* Allocate thread args and handle array and space for the file. Read the complete file. */

ThArg = malloc (NPr * sizeof (THREADARG)); /* Thread args. */ ThreadHandle = malloc (NPr * sizeof (HANDLE)); pRecords = malloc (FsLow + sizeof (TCHAR)); ReadFile (hFile, pRecords, FsLow, &nRead, NULL); CloseHandle (hFile);

LowRecNo = 0; /* Create the sorting threads. */ for (iTh = 0; iTh < NPr; iTh++) { ThArg [iTh].iTh = iTh; ThArg [iTh].LowRec = pRecords + LowRecNo; ThArg [iTh].HighRec = pRecords + (LowRecNo + nRecTh); LowRecNo += nRecTh; ThreadHandle [iTh] = (HANDLE) _beginthreadex (NULL, 0, ThSort, &ThArg [iTh], CREATE_SUSPENDED, &ThId); }

53

Bi ging mn hc: L p trinh Windows


for (iTh = 0; iTh < NPr; iTh++) /* Run all sort threads. */ ResumeThread (ThreadHandle [iTh]); WaitForSingleObject (ThreadHandle [0], INFINITE); for (iTh = 0; iTh < NPr; iTh++) CloseHandle (ThreadHandle [iTh]);

StringEnd = (LPTSTR) pRecords + FsLow; *StringEnd = '\0'; if (!NoPrint) printf ("\n%s", (LPCTSTR) pRecords); free (pRecords); free (ThArg); free (ThreadHandle); return 0; } /* End of _tmain. */

static VOID MergeArrays (LPRECORD, LPRECORD); DWORD WINAPI ThSort (PTHREADARG pThArg) { DWORD GrpSize = 2, RecsInGrp, MyNumber, TwoToI = 1; LPRECORD First;

MyNumber = pThArg->iTh; First = pThArg->LowRec; RecsInGrp = pThArg->HighRec - First; qsort (First, RecsInGrp, RECSIZE, KeyCompare); while ((MyNumber % GrpSize) == 0 && RecsInGrp < nRec) { /* Merge with the adjacent sorted array. */ WaitForSingleObject ( ThreadHandle [MyNumber + TwoToI], INFINITE); MergeArrays (First, First + RecsInGrp); RecsInGrp *= 2; GrpSize *= 2; TwoToI *= 2; } _endthreadex (0);

54

Bi ging mn hc: L p trinh Windows


return 0; /* Suppress a warning message. */ }

static VOID MergeArrays (LPRECORD p1, LPRECORD p2) { DWORD iRec = 0, nRecs, i1 = 0, i2 = 0; LPRECORD pDest, p1Hold, pDestHold;

nRecs = p2 - p1; pDest = pDestHold = malloc (2 * nRecs * RECSIZE); p1Hold = p1; while (i1 < nRecs && i2 < nRecs) { if (KeyCompare ((LPCTSTR) p1, (LPCTSTR) p2) <= 0) { memcpy (pDest, p1, RECSIZE); i1++; p1++; pDest++; }

else { memcpy (pDest, p2, RECSIZE); i2++; p2++; pDest++; } }

if (i1 >= nRecs) memcpy (pDest, p2, RECSIZE * (nRecs - i2)); else memcpy (pDest, p1, RECSIZE * (nRecs - i1));

memcpy (p1Hold, pDestHold, 2 * nRecs * RECSIZE); free (pDestHold); return; } Bi tp: Bi tp 1: Vit chng trnh hin thi tt c cc thng tin v tin trnh v lung cua mt tin trnh ang chay.

55

Bi ging mn hc: L p trinh Windows


Chng 5: Cc dich v ca Windows 1. T ng quan v dich vu trn Windows Cc dich vu cua Windows, ban u c gi l cc dich vu NT, cung cp kh nng qun l oi hoi cc chng trnh theo kiu server phi c chay trn dong lnh, hoc vo thi im h thng khi ng, trc khi bt c ngi dung no ng nhp, v cng co th thc hin tam dng, khi phuc, kt thuc. Cc dich vu c a ra nhm p ng yu cu ny. qun l cc dich vu chung ta co th dung cng cu Service Control Manager cung cp sn bi Windows, cng cu ny s thc hin ba bc qun l mt dich vu: + Gi ti hm main() cua dich vu + Chuyn i t hm main() sang hm ServiceMain() + Ghi cc con tro qun l co th p ng lai cc lnh t SCM

2. Cc thnh phn ca mt dich v 2.1 Hm main() Hm ny c gi bi SCM, co nhim vu l khai bo dich vu vi SCM v bt u thc hin cng vic cua mt dich vu. 2.2 Hm ServiceMain() Hm ServiceMain() l mt dang tng t nh hm main() vi cc tham s tng t, no thc hin cc tc vu chnh cua mt dich vu. 2.3 Ki m soat dich vu qua cac Handler kim sot dich vu, chung ta s dung cc hm sau: DWORD WINAPI HandlerEx ( DWORD dwControl, DWORD dwEventType,

56

Bi ging mn hc: L p trinh Windows


LPVOID lpEventData, LPVOID lpContext) 3. Vi du: dich v n gin trn Windows #include "EvryThng.h" #include "ClntSrvr.h" #define UPDATE_TIME 1000 /* One second between updates. */

VOID LogEvent (LPCTSTR, DWORD, BOOL); void WINAPI ServiceMain (DWORD argc, LPTSTR argv []); VOID WINAPI ServerCtrlHandlerEx(DWORD, DWORD, LPVOID, LPVOID); void UpdateStatus (int, int); /* Calls SetServiceStatus. */ int ServiceSpecific (int, LPTSTR *); /* Former main program. */ volatile static BOOL ShutDown = FALSE, PauseFlag = FALSE; static SERVICE_STATUS hServStatus; static SERVICE_STATUS_HANDLE hSStat; /* Handle to set status. */

static LPTSTR ServiceName = _T ("SocketCommandLineService"); static LPTSTR LogFileName = _T ("CommandLineServiceLog.txt");

/* Main routine that starts the service control dispatcher. */ VOID _tmain (int argc, LPTSTR argv []) { SERVICE_TABLE_ENTRY DispatchTable [] = { { ServiceName, ServiceMain }, { NULL, NULL } };

StartServiceCtrlDispatcher (DispatchTable); return 0; }

/* ServiceMain entry point, called when the service is created. */ void WINAPI ServiceMain (DWORD argc, LPTSTR argv [])

57

Bi ging mn hc: L p trinh Windows


{ DWORD i, Context = 1; /* Set the current directory and open a log file, appending to an existing file. */

/* Set all server status data members. */ hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; hServStatus.dwCurrentState = SERVICE_START_PENDING; hServStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN SERVICE_ACCEPT_PAUSE_CONTINUE; hServStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIF0C_ERROR; hServStatus.dwServiceSpecificExitCode = 0; hServStatus.dwCheckPoint = 0; hServStatus.dwWaitHint = 2 * CS_TIMEOUT; |

hSStat = RegisterServiceCtrlHandlerEx (ServiceName, ServerCtrlHandler, &Context); SetServiceStatus (hSStat, &hServStatus);

/* Start service-specific work; generic work is complete. */ if (ServiceSpecific (argc, argv) != 0) { hServStatus.dwCurrentState = SERVICE_STOPPED; hServStatus.dwServiceSpecificExitCode = 1; /* Server initialization failed. */ SetServiceStatus (hSStat, &hServStatus); return; } /* We will only return here when the ServiceSpecific function completes, indicating system shutdown. */ UpdateStatus (SERVICE_STOPPED, 0); return; }

58

Bi ging mn hc: L p trinh Windows


void UpdateStatus (int NewStatus, int Check) /* Set a new service status and checkpoint -either specific value or increment. */ { if (Check < 0) hServStatus.dwCheckPoint++; else hServStatus.dwCheckPoint = Check; if (NewStatus >= 0) hServStatus.dwCurrentState = NewStatus; SetServiceStatus (hSStat, &hServStatus); return; }

/* Control handler function, invoked by the SCM to run */ /* in the same thread as the main program. */ /* The last three parameters are not used, and the pre-NT5 */ /* handlers would also work in this example. */ VOID WINAPI ServerCtrlHandlerEx (DWORD Control, DWORD EventType, LPVOID lpEventData, LPVOID lpContext) { swsitch (Control) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: ShutDown = TRUE; /* Set the global shutdown flag. */ UpdateStatus (SERVICE_STOP_PENDING, -1); break; case SERVICE_CONTROL_PAUSE: PauseFlag = TRUE; /* Interrogated periodically. */ break; case SERVICE_CONTROL_CONTINUE: PauseFlag = FALSE; break; case SERVICE_CONTROL_INTERROGATE: break; default: if (Control > 127 && Control < 256) /* User defined. */

59

Bi ging mn hc: L p trinh Windows


break; } UpdateStatus (-1, -1); /* Increment checkpoint. */ return; }

/* This is the service-specific function, or "main," and is called from the more generic ServiceMain. In general, you can take any server, such as ServerNP.c, and rename "main" as "ServiceSpecific"; putting code right here. But some changes are required to update status. */

int ServiceSpecific (int argc, LPTSTR argv []) { UpdateStatus (-1, -1); /* Increment the checkpoint. */ /* ... Initialize system ... */ /* Be sure to update the checkpoint periodically. */

return 0; } 4. Qun ly cc dich v ca Windows 4.1 Cc phng php kim sot cc dich v ca Windows qun l cc dich vu cua Windows ta co hai cch: mt l dung cng cu SCM, hai l g trc tip cc lnh trn dong lnh. 4.2 Vi d : i u khi n cac dich vu cua Windows #include "EvryThng.h"

static SC_HANDLE hScm; static BOOL Debug;

int _tmain (int argc, LPTSTR argv []) { BOOL Exit = FALSE; TCHAR Command [MAX_COMMAND_LINE + 10], *pc;

60

Bi ging mn hc: L p trinh Windows


DWORD i, LocArgc; /* Local argc. */ TCHAR argstr [MAX_ARG] [MAX_COMMAND_LINE]; LPTSTR pArgs [MAX_ARG];

/* Prepare the local "argv" array as pointers to strings. */ for (i = 0; i < MAX_ARG; i++) pArgs [i] = argstr [i];

/* Open the SC Control Manager on the local machine. */ hScm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);

/* Main command processing loop. */ _tprintf (_T ("\nWindows Service Management")); while (!Exit) { _tprintf (_T ("\nSM$")); _fgetts (Command, MAX_COMMAND_LINE, stdin); ... Similar to JobShell ... if (_tcscmp (argstr [0], _T ("create")) == 0) { Create (LocArgc, pArgs, Command); } ... Similarly for all commands ... } CloseServiceHandle (hScm); return 0; }

int Create (int argc, LPTSTR argv [], LPTSTR Command) { /* Create a new service as a "demand start" service: argv [1]: service Name argv [2]: display Name argv [3]: binary executable */ SC_HANDLE hSc; TCHAR CurrentDir [MAX_PATH + 1], Executable [MAX_PATH + 1];

61

Bi ging mn hc: L p trinh Windows


hSc = CreateService (hScm, argv [1], argv [2], SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, Executable, NULL, NULL, NULL, NULL, NULL); return 0; }

/* Delete a service -- argv [1]: ServiceName to delete. */

int Delete (int argc, LPTSTR argv [], LPTSTR Command) { SC_HANDLE hSc; hSc = OpenService (hScm, argv [1], DELETE); DeleteService (hSc); CloseServiceHandle (hSc); return 0; }

/* Start a named service -- argv [1]: service name to start. */ int Start (int argc, LPTSTR argv [], LPTSTR Command) { SC_HANDLE hSc; TCHAR WorkingDir [MAX_PATH + 1]; LPTSTR pWorkingDir = WorkingDir; LPTSTR argvStart [] = {argv [1], WorkingDir};

GetCurrentDirectory (MAX_PATH + 1, WorkingDir); hSc = OpenService(hScm, argv [1], SERVICE_ALL_ACCESS); /* Start the service with one arg, the working directory. */ /* Note: The service name agrees, by default, with the name */ /* /* associated with the handle, hSc, by OpenService. */ But, the ServiceMain function does not verify this. */

StartService (hSc, 2, argvStart); CloseServiceHandle (hSc);

62

Bi ging mn hc: L p trinh Windows


return 0; }

/* Control a named service. argv [1]: service name to control. argv [2]: Control command: stop, pause, resume, interrogate. */ static LPCTSTR Commands [] = {"stop," "pause," "resume," "interrogate," "user"}; static DWORD Controls [] = { SERVICE_CONTROL_STOP, SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_CONTINUE, 128}; SERVICE_CONTROL_INTERROGATE,

int Control (int argc, LPTSTR argv [], LPTSTR Command) { SC_HANDLE hSc; SERVICE_STATUS ServiceStatus; DWORD dwControl, i; BOOL Found = FALSE;

for (i= 0; i < sizeof (Controls)/sizeof (DWORD) && !Found; i++) Found = (_tcscmp (Commands [i], argv [2]) == 0); if (!Found) { _tprintf (_T ("\nIllegal Control Command %s"), argv [1]); return 1; } dwControl = Controls [i - 1]; hSc = OpenService(hScm, argv [1], SERVICE_INTERROGATE | SERVICE_PAUSE_CONTINUE | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | SERVICE_QUERY_STATUS); ControlService (hSc, dwControl, &ServiceStatus);

if (dwControl == SERVICE_CONTROL_INTERROGATE) { QueryServiceStatus (hSc, &ServiceStatus);

63

Bi ging mn hc: L p trinh Windows


printf (_T ("Status from QueryServiceStatus\n")); printf (_T ("Service Status\n")); ... Print all other status information ... } if (hSc != NULL) CloseServiceHandle (hSc); return 0; } Bi tp: Bi tp 1: Vit dich vu ghi lai nht k cc ln login v s dung h thng trn Windows. Bi tp 2: Vit chng trnh qun l cc dich vu cua Windows.

64

Bi ging mn hc: L p trinh Windows


Chng 6: L p trnh Socket 1. Khi nim sockets trn Windows Socket: l mt thc th logic ai din cho kt ni gia cc my tnh trn mt h thng mang. T t ca cac truy n thng gia cac may tinh trn m t h th ng ma ng c thc hi n thng qua socket . Co hai m hnh lp trnh mang : m hinh client /server va m hinh peer 2 peer (mang ngang hng). Theo m hinh client/server: Server: m m t dich vu b ng cach ta o ra m t i t ng ServerSocket vi tham s la ia ch c ng k t n i , sau o nh n k t n i t phia client b ng cach s du ng ham accept (), l y cc lung d liu vo /ra cua client thc hi n truy n d li u , thc hi n cac x ly c n thi t , tr kt qu cho client v ong k t n i ti client, dich vu kt thuc. 2. Cc hm sockets phia server Cc hm socket pha server m chung ta cn quan tm gm co: int bind ( SOCKET s, const struct sockaddr *saddr, int namelen); int listen (SOCKET s, int nQueueSize); SOCKET accept ( SOCKET s, LPSOCKADDR lpAddr, LPINT lpAddrLen); Vi d: struct sockaddr_in SrvSAddr; /* Server address struct. */ struct sockaddr_in ConnectAddr; SOCKET SrvSock, sockio; ... SrvSock = socket (AF_INET, SOCK_STREAM, 0); SrvSAddr.sin_family = AF_INET; SrvSAddr.sin_addr.s_addr = htonl (INADDR_ANY); SrvSAddr.sin_port = htons (SERVER_PORT); bind (SrvSock, (struct sockaddr *) &SrvSAddr, sizeof SrvSAddr); listen (SrvSock, 5); AddrLen = sizeof (ConnectAddr);

65

Bi ging mn hc: L p trinh Windows


sockio = accept (SrvSock, (struct sockaddr *) &ConnectAddr, &AddrLen); ... Receive requests and send responses ... shutdown (sockio); closesocket (sockio); 3. Cc hm sockets phia client Cc hm socket pha client cn phi quan tm l: int connect ( SOCKET s, LPSOCKADDR lpName, int nNameLen); int send ( SOCKET s, const char * lpBuffer, int nBufferLen, int nFlags); V du: SOCKET ClientSock; ... ClientSock = socket (AF_INET, SOCK_STREAM, 0); memset (&ClientSAddr, 0, sizeof (ClientSAddr)); ClientSAddr.sin_family = AF_INET; ClientSAddr.sin_addr.s_addr = inet_addr (argv [1]); ClientSAddr.sin_port = htons (SERVER_PORT); ConVal = connect (ClientSock, (struct sockaddr *) &ClientSAddr, sizeof (ClientSAddr)); 4. ng dng mang n gin 4.1 Phia server #define _NOEXCLUSIONS #include "EvryThng.h" #include "ClntSrvr.h" /* Defines request and response records. */

struct sockaddr_in SrvSAddr;

66

Bi ging mn hc: L p trinh Windows


/* Server's socket address structure. */ struct sockaddr_in ConnectSAddr; /* Connected socket. */ WSADATA WSStartData; /* Socket library data structure. */

typedef struct SERVER_ARG_TAG { /* Server thread arguments. */ volatile DWORD number; volatile SOCKET sock; volatile DWORD status; /* Explained in main thread comments. */ volatile HANDLE srv_thd; HINSTANCE dlhandle; /* Shared library handle. */ } SERVER_ARG; volatile static ShutFlag = FALSE; static SOCKET SrvSock, ConnectSock;

int _tmain (DWORD argc, LPCTSTR argv []) { /* Server listening and connected sockets. */ BOOL Done = FALSE; DWORD ith, tstatus, ThId; SERVER_ARG srv_arg [MAX_CLIENTS]; HANDLE hAcceptTh = NULL; HINSTANCE hDll = NULL;

/* Initialize the WSA library, Ver 2.0, although 1.1 will work. */ WSAStartup (MAKEWORD (2, 0), &WSStartData);

/* Open command library DLL if specified on command line. */ if (argc > 1) hDll = LoadLibrary (argv [1]); /* Initialize thread arg array. */ for (ith = 0; ith < MAX_CLIENTS; ith++) { srv_arg [ith].number = ith; srv_arg [ith].status = 0; srv_arg [ith].sock = 0; srv_arg [ith].dlhandle = hDll; srv_arg [ith].srv_thd = NULL;

67

Bi ging mn hc: L p trinh Windows


} /* Follow standard server socket/bind/listen/accept sequence. */ SrvSock = socket (AF_INET, SOCK_STREAM, 0); SrvSAddr.sin_family = AF_INET; SrvSAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); SrvSAddr.sin_port = htons ( SERVER_PORT ); bind (SrvSock, (struct sockaddr *) &SrvSAddr, sizeof SrvSAddr); listen (SrvSock, MAX_CLIENTS);

/* Main thread becomes listening/connecting/monitoring thread. */ /* Find an empty slot in the server thread arg array. */ /* status values: 0 -- slot is free; 1 -- thread stopped; 2 -- thread running; 3 -- stop entire system. */ while (!ShutFlag) { for (ith = 0; ith < MAX_CLIENTS && !ShutFlag; ) { if (srv_arg [ith].status==1 || srv_arg [ith].status==3) { /* Thread stopped, normally or by shutdown request. */ WaitForSingleObject (srv_arg[ith].srv_thd INFINITE); CloseHandle (srv_arg[ith].srv_thd); if (srv_arg [ith].status == 3) ShutFlag = TRUE; else srv_arg [ith].status = 0; /* Free thread slot. */ } if (srv_arg [ith].status == 0 || ShutFlag) break; ith = (ith + 1) % MAX_CLIENTS; if (ith == 0) Sleep (1000); /* Break the polling loop. */ /* Alternative: use an event to signal a free slot. */ } /* Wait for a connection on this socket. */ /* Separate thread so we can poll the ShutFlag flag. */ hAcceptTh = (HANDLE)_beginthreadex (NULL, 0, AcceptTh, &srv_arg [ith], 0, &ThId);

68

Bi ging mn hc: L p trinh Windows


while (!ShutFlag) { tstatus = WaitForSingleObject (hAcceptTh, CS_TIMEOUT); if (tstatus == WAIT_OBJECT_0) break; /* Connection made. */ } CloseHandle (hAcceptTh); hAcceptTh = NULL; /* Prepare for next connection. */ }

_tprintf (_T ("Server shutdown. Wait for all srvr threads\n")); /* Terminate the accept thread if it is still running. * See the Web site for more detail on this shutdown logic. */ if (hDll != NULL) FreeLibrary (hDll); if (hAcceptTh != NULL) TerminateThread (hAcceptTh, 0); /* Wait for any active server threads to terminate. */ for (ith = 0; ith < MAX_CLIENTS; ith++) if (srv_arg [ith].status != 0) { WaitForSingleObject (srv_arg[ith].srv_thd, INFINITE); CloseHandle (srv_arg[ith].srv_thd); } shutdown (SrvSock, 2); closesocket (SrvSock); WSACleanup (); return 0; }

static DWORD WINAPI AcceptTh (SERVER_ARG * pThArg) { /* Accepting thread that allows the main thread to poll the */ /* shutdown flag. This thread also creates the server thread. */ LONG AddrLen, ThId;

AddrLen = sizeof (ConnectSAddr); pThArg->sock = accept (SrvSock, /* This is a blocking call. */

69

Bi ging mn hc: L p trinh Windows


(struct sockaddr *) &ConnectSAddr, &AddrLen); /* A new connection. Create a server thread. */ pThArg->status = 2; pThArg->srv_thd = (HANDLE) _beginthreadex (NULL, 0, Server, pThArg, 0, &ThId); return 0; /* Server thread remains running. */ } static DWORD WINAPI Server (SERVER_ARG * pThArg) /* Server thread function. Thread created on demand. */ { /* Each thread keeps its own request, response, and bookkeeping data structures on the stack. */ /* ... Standard declarations from serverNP omitted ... */ SOCKET ConnectSock; int Disconnect = 0, i; int (*dl_addr)(char *, char *); char *ws = " \0\t\n"; /* White space. */

GetStartupInfo (&StartInfoCh); ConnectSock = pThArg->sock; /* Create a temp file name. */ sprintf (TempFile, "%s%d%s", "ServerTemp", pThArg->number, ".tmp");

while (!Done && !ShutFlag) { /* Main command loop. */ Disconnect = ReceiveRequestMessage (&Request, ConnectSock); Done = Disconnect || (strcmp (Request.Record, "$Quit") == 0) || (strcmp (Request.Record, "$ShutDownServer") == 0); if (Done) continue; /* Stop this thread on "$Quit" or "$ShutDownServer". */ hTmpFile = CreateFile (TempFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &TempSA, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

70

Bi ging mn hc: L p trinh Windows


/* Check for a DLL command. For simplicity, shared */ /* library commands take precedence over process commands. First, extract the command name. */

i = strcspn (Request.Record, ws); /* Length of token. */ memcpy (sys_command, Request.Record, i); sys_command [i] = '\0';

dl_addr = NULL; /* Will be set if GetProcAddress succeeds. */ if (pThArg->dlhandle != NULL) { /* Try server "in process." */ dl_addr = (int (*)(char *, char *)) GetProcAddress (pThArg->dlhandle, sys_command); if (dl_addr != NULL) __try { /* Protect server process from exceptions in DLL. */ (*dl_addr) (Request.Record, TempFile); } __except (EXCEPTION_EXECUTE_HANDLER { ReportError (_T ("Exception in DLL"), 0, FALSE); } } } if (dl_addr == NULL) { /* No in-process support. */ /* Create a process to carry out the command. */ /* ... Same as in serverNP ... */ } /* ... Same as in serverNP ... */

} /* End of main command loop. Get next command. */

/* End of command loop. Free resources; exit from the thread. */

_tprintf (_T ("Shutting down server# %d\n"), pThArg->number); shutdown (ConnectSock, 2); closesocket (ConnectSock);

71

Bi ging mn hc: L p trinh Windows


pThArg->status = 1; if (strcmp (Request.Record, "$ShutDownServer") == 0) { pThArg->status = 3; ShutFlag = TRUE; } return pThArg->status; } 4.2 Phia client #define _NOEXCLUSIONS /* Required to include socket definitions. */ #include "EvryThng.h" #include "ClntSrvr.h" /* Defines request and response records. */ /* Message functions for request and response. */ /* ReceiveResponseMessage also prints the received messages. */ static DWORD SendRequestMessage (REQUEST *, SOCKET); static DWORD ReceiveResponseMessage (RESPONSE *, SOCKET);

struct sockaddr_in ClientSAddr; /* Clients's socket address. */

int _tmain (DWORD argc, LPTSTR argv []) { SOCKET ClientSock = INVALID_SOCKET; REQUEST Request; /* See ClntSrvr.h. */ RESPONSE Response; /* See ClntSrvr.h. */ WSADATA WSStartData; /* Socket library data structure. */ BOOL Quit = FALSE; DWORD ConVal, j; TCHAR PromptMsg [] = _T ("\nEnter Command> "); TCHAR Req [MAX_RQRS_LEN]; TCHAR QuitMsg [] = _T ("$Quit"); /* Request: shut down client. */ TCHAR ShutMsg [] = _T ("$ShutDownServer"); /* Stop all threads. */ CHAR DefaultIPAddr [] = "127.0.0.1"; /* Local system. */

72

Bi ging mn hc: L p trinh Windows


/* Initialize the WSA library, Ver 2.0, although 1.1 will work. */ WSAStartup (MAKEWORD (2, 0), &WSStartData);

/* Connect to the server. */ /* Follow the standard client socket/connect sequence. */ ClientSock = socket (AF_INET, SOCK_STREAM, 0); memset (&ClientSAddr, 0, sizeof (ClientSAddr)); ClientSAddr.sin_family = AF_INET; if (argc >= 2) ClientSAddr.sin_addr.s_addr = inet_addr (argv [1]); else ClientSAddr.sin_addr.s_addr = inet_addr (DefaultIPAddr); ClientSAddr.sin_port = htons (SERVER_PORT); /* Defined as 1070. */ connect (ClientSock, (struct sockaddr *) &ClientSAddr, sizeof (ClientSAddr)); /* Main loop to prompt user, send request, receive response. */ while (!Quit) { _tprintf (_T ("%s"), PromptMsg); /* Generic input, but command to server must be ASCII. */ _fgetts (Req, MAX_RQRS_LEN-1, stdin); for (j = 0; j <= _tcslen (Req); j++) Request.Record [j] = Req [j]; /* Get rid of the new line at the end. */ Request.Record [strlen (Request.Record) - 1] = '\0'; if (strcmp (Request.Record, QuitMsg) == 0 || strcmp (Request.Record, ShutMsg) == 0) Quit = TRUE; SendRequestMessage (&Request, ClientSock); ReceiveResponseMessage (&Response, ClientSock); }

shutdown (ClientSock, 2); /* Disallow sends and receives. */ closesocket (ClientSock); WSACleanup ();

73

Bi ging mn hc: L p trinh Windows


_tprintf (_T ("\n****Leaving client\n")); return 0; } 5. Windows Sockets 2.0 L phin bn mi nht cua Windows cho lp trnh mang theo m hnh socket. Bi tp: Bi tp 1: Vit chng trnh client/server cho php client nhp vo mt xu, gi sang server, server s tr v s t co trong xu.

74

Bi ging mn hc: L p trinh Windows


Chng 7: Th vin lin k t ng Cc th vin lin kt ng Dynamic -link Libararies la m t trong cac ph n t quan tro ng nh t cua h i u hanh Windows . H u h t cac thao tac truy c p ia cng trn Windows u c thc hi n bi cac chng trinh ho c cac file lin k t ng . Cho n thi i m nay chung ta a vi t r t nhi u c c chng trnh v by gi l luc chung ta xem xt vic vit cc th vin lin k t ng. R t nhi u nguyn t c trong vi c vi t cac chng trinh cung c ap du ng trong vi c vi t cac th vi n song co m t s thay i quan tro ng. 7.1. Khi nim v ng dng ca th vin lin kt ng Nh cac ba n th y m t chng trinh trn Windows la m t file cha y thng ta o ra m t ho c m t s ca s chng trinh va s du ng m t vong l p thng i p nh n cac thng tin input t ngi dung . Cc th vin lin kt ng thng khng phi l cc file chay trc tip v chung thng khng nhn cc thng ip . Chung thng l cc file ring bit cha cc hm co th c gi bi cc chng trnh v cc th vin khc thc hin mt cng vic cu th nao o . M t th vi n lin k t ng thng c na p vao m t nh thc hi n khi m t module chng trnh khc gi ti mt hm trong th vin. Thu t ng lin k t ng dynamic link c p ti qua trinh ma Windows s du ng lin k t m t li go i ham trong m t module chng trinh vi cac ham thc s n m trong m t th vi n lin k t ng. Cc lin kt tnh c thc hin khi trnh bin dich tin hnh bc lin k t (link) cc file object (.obj), cc th vin run-time (*.lib) v s dung mt chng trnh bin dich ti nguyn tao thnh mt file chay .exe. Qu trnh lin kt ng khng din ra vo luc bin dich v lin kt chng trnh m din ra vo luc chng trnh chay. 7.2. H thng th vin lin kt ng ca Windows Cc th vin Kernel 32.dll, user32.dll va gdi 32.dll, r t nhi u cac file i u khi n khac ch ng ha n nh keyboard .drv, system.drv v mouse .drv cung nh cac trinh i u khi n card mn hnh v my in u l cc th vin lin kt ng . Cc th vin ny u alf cc th vin m hu ht cc chng trnh trn Windows u s dung. M t vai th vi n lin k t ng (ch ng ha n nh cac font ch ) c go i la cac th vi n tai nguyn (resource only ). Cc th vin ny ch cha d liu (th ng la di da ng cac tai nguyn) v khng cha m chng trnh . Do o m t trong cac mu c ich cua c c th vin lin k t ng la cung c p cac ham va cac tai nguyn co th c s du ng bi cac chng trinh khc. Trong cac h i u hanh ngay xa (ki u nh DOS) ch co h iu hnh mi cha cc thu tuc m cc chng trn h khac co th go i n hoan thanh m t cng vi c gi o . Trn Windows qua trinh m t module chng trinh go i ti m t ham trong m t module chng trinh khc l rt thng xuyn . B ng cach vi t cac Dll chung ta co thm cac m r ng cho h i u hnh. M c du m t module th vi n lin k t ng co th co b t c ph n tn m r ng nao (ch ng ha n nh .exe hay .com) nhng ph n tn m r ng chu n cua cac th vi n lin k t ng trn Windows la .dll. Ch co cc th vin lin kt ng co phn tn m rng l dll mi c t ng na p vao b nh bi Windows cac th vi n co ph n tn m r ng khac se c na p thng qua vi c go i ti cac ham LoadLibrary ho c LoadLibraryEx . Chung ta th ng thy cc th vin lin kt ng c s dung trong cc chng trnh ln. Ch ng ha n nh chung ta vi t m t goi ph n m m k toan ln cha m t vai chng trinh khc nhau. Cc chng trnh ny s dung nhiu thu tuc chung do o chung ta co th k t h p

75

Bi ging mn hc: L p trinh Windows


cc hm ny vo mt th vin lin kt tnh (*.lib) sau o thm vao mi module chng trinh trong qua trinh bin dich cac chng trinh nay . Tuy nhin cach ti p c n o se la lang phi vi mi chng trinh se cha cac oa n ma gi ng nhau va hn na n u chung ta thay i m t ham no o trong th vin chung ta s phi lin kt lai tt c cc chng trnh co s dung th vin o. Nhng n u chung ta cho t t ca cac ham o vao m t th vi n lin k t ng ch ng ha n nh account.dll ch ng ha n thi se giai quy t c ca hai v n trn . Ch co module cn thit cha t t ca cac ma cua cac ham c s du ng bi t t ca cac chng trinh i u na y se oi hoi it khng gian ia cng hn va ng thi oi hoi it b nh hn khi nhi u chng trinh cung cha y ng thi, hn na chung ta co th thay i cac cai t cua cac ham trong th vi n ma khng c n thi t phai lin k t la i th vi n vi cac chng trinh. Cc th vin lin kt ng cng co th l c sn phm thng mai , hi n nay co r t nhi u hng chuyn cung cp cc hm th vin dnh cho pht trin mt loai sn phm phn mm no o ch ng ha n nh DirectX la m t t p cac th vi n lin k t ng danh cho vi c vi t cac chng trinh ho a cao c p . Th vin: m t li ngan y. (One word, many meanings) M t ph n cac nh m ln i vi cac th vi n lin k t ng l vic s dung cua thut ng th vi n (library) trong m t s cac khung canh khac nhau . Bn ca nh cac th vi n lin k t ng chung ta con noi n cac th vi n i t ng va cac th vi n import. M t th vi n i t ng la m t file co ph n m r ng la .lib cha cac oa n ma chng trnh s c thm vo file .exe trong qua trinh lin k t tinh . Ch ng ha n trong VC ++ th vi n i t ng run-time thng lin k t vi cac chng trinh la libc.lib. M t th vin import l mt dang c bit cua cc file th vin i tng . Gi ng nh cac th vi n i t ng cac th vi n import co ph n m r ng la .lib va c s du ng bi trinh bin dich gii quyt cc li gi hm trong cc c hng trinh cua chung ta vi t ra . Tuy nhin cac th vi n import nay khng cha cac ma chng trinh . Thay vao o chung cung c p cho trinh lin k t cac thng tin c n thi t e thi t l p cac bang chuy n (relocation table) trong file .exe thc hi n cac lin k t ng . Cc file kernel 32.lib, user32.lib, gdi32.lib i kem vi cac trinh bin dich cua Microsoft u la cac th vi n import . N u chung ta go i ti m t ham ch ng ha n nhu Rectangle thi file gdi 32.lib se bo cho trnh lin kt bit rng o l mt hm trong th vi n lin k t ng gdi 32.dll. Thng tin nay se c cha trong file chng trinh (*.exe) Windows co th thc hi n cac lin k t ng khi chng trinh cua chung ta c thc hi n. Cc th vin i tng v cc th vin import u c s dung trong qu trnh pht tri n cac chng trinh . Cc th vin lin kt ng c s dung trong qu trnh chng trnh chay. M t th vi n lin k t ng phi sn co trn a chng trnh co th s dung no khi chay. Khi Windows c n na p m t module DLL trc khi cha y m t chng trinh oi hoi s dung hm trong no file th vin phi nm cung th muc vi file .exe, trong th mu c hi n thi, trong th mu c system cua h i u hanh ho c n m trong th mu c co trong bi n mi trng PATH cua h i u hanh (h i u hanh se ti n hanh tim ki m th vi n theo th t o). 7.3. Cc bc to mt th vin DLL M c du tng cua cc th vin lin kt ng l co th s dung vi nhiu ng dung nhng chung ta se vi t m t ng du ng demo s du ng m t th vi n lin k t ng n gian .

76

Bi ging mn hc: L p trinh Windows


Chung ta s tao mt mt th vin lin kt ng l edrlib .dll (Easy drawing routine ). Hm th vin ny s ch cha mt hm n gin thc hin cng vic v ra mt xu trong ng dung demo cua chung ta. ta o ra m t th vi n lin k t ng chung ta c n co m t cach ti p c n khac s o vi cach m chung ta vn dung vit cc ng dung . VC++ phn bi t gia cac khai ni m workspace v project . M t project thng la m t ng du ng ho c m t th vi n lin k t ng . M t workspace co th g m nhi u project . Cho n thi i m nay chung ta mi chi vi t cac workspace chi co 1 project. Trong ph n nay chung ta se ta o m t workspace co hai project , m t cho vi c ta o dll va m t cho vi c go i ti file dll o. Cc bc tao ng dung vi Visual Studio .NET 2003 nh sau: 1. Tao 1 Solution (Dll1 ch ng ha n) rng (Blank Solution) 2. Thm m t project cha file dll cho ng du ng (chn New Project Win32 Project) v g tn cua Project l SimpleDll. 3. Trong h p thoa i Application Setting chn DLL (Application Type) v chn muc Empty. 4. Thm file ma ngu n cho Project va go n i dung cua file dll vao :

/*---------------------simpledll.h header file

----------------------*/

#ifdef __cplusplus #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif

EXPORT BOOL CALLBACK EdrCenterTextA (HDC, PRECT, PCSTR) ; EXPORT BOOL CALLBACK EdrCenterTextW (HDC, PRECT, PCWSTR) ;

#ifdef UNICODE #define EdrCenterText EdrCenterTextW #else #define EdrCenterText EdrCenterTextA #endif

77

Bi ging mn hc: L p trinh Windows


/*------------------------------------------------simpledll.c -- Easy Drawing Routine Library module

(c) Charles Petzold, 1998 -------------------------------------------------*/

#include <windows.h> #include "simpledll.h"

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { return TRUE ; }

EXPORT BOOL CALLBACK EdrCenterTextA (HDC hdc, PRECT prc, PCSTR pString) { int iLength ; SIZE size ;

iLength = lstrlenA (pString) ; GetTextExtentPoint32A (hdc, pString, iLength, &size) ; return TextOutA (hdc, (prc->right - prc->left - size.cx) / 2, (prc->bottom - prc->top - size.cy) / 2, pString, iLength) ; }

EXPORT BOOL CALLBACK EdrCenterTextW (HDC hdc, PRECT prc, PCWSTR pString) { int iLength ; SIZE size ;

78

Bi ging mn hc: L p trinh Windows


iLength = lstrlenW (pString) ; GetTextExtentPoint32W (hdc, pString, iLength, &size) ; return TextOutW (hdc, (prc->right - prc->left - size.cx) / 2, (prc->bottom - prc->top - size.cy) / 2, pString, iLength) ; } 5. Tao mt Project Win 32 Project, sau o cho n ki u Project la Application, tao file .c cho ng du ng va go n i dung ng du ng vao nh sau: #include <windows.h> #include "..\\SimpleDll\\simpledll.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("StrProg") ; HWND MSG hwnd ; msg ; wndclass ;

WNDCLASS

wndclass.style

= CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance wndclass.hIcon wndclass.hCursor = hInstance ; = LoadIcon (NULL, IDI_APPLICATION) ; = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ;

79

Bi ging mn hc: L p trinh Windows


return 0 ; }

hwnd = CreateWindow (szAppName, TEXT ("DLL Demonstration Program"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ;

PAINTSTRUCT ps ; RECT rect ;

switch (message) { case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; EdrCenterText (hdc, &rect, TEXT ("This string was displayed by a DLL")) ;

80

Bi ging mn hc: L p trinh Windows


EndPaint (hwnd, &ps) ; return 0 ;

case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } 6. t ch dich l Project th hai phu thu c (dependencies) vo Project th nh t va th mu c Output cung ta m cua hai Project la ../Release. 7. Dich v chay chng trnh. y chung ta co hai phin bn cua mt hm trong th vin lin kt ng c s dung, i u nay cho php dung cc hm co h tr Unicode trong trng hp h thng co h tr v ngc lai s dung mt hm khng co Unicode , thng tn cua ham se co thm ch W n u co h tr Unicode v A nu khng. ng thi chung ta cng t h y trong ma cua th vi n co m t ham DllMain , hm ny co vai tro tng t nh ham WinMain trong m t chng trinh . Tc dung cua hm DllMain l khi ta o va thu h i b nh va nhng th lin quan khac , chung ta s bn ti vn ny cui chng, hi n ta i chi c n return TRUE la n . i u bi n con la i co le la inh danh EXPORT . Cc hm trong mt th vin lin kt ng c s du ng bi cac ng du ng khac phai c xu t kh u . i u nay khng lin quan ti cc vn thng mai thng thng m ch l mt ch thi m bo trnh bin dich s thm tn hm vo th vin import simpledll .lib trinh lin k t co th a cac thng tin phu h p vao chng trinh (file *.exe) co th nap cc th vin dll khi chng trnh chay . inh danh EXPORT con bao g m chi inh lp cha __declspec(dllexport) v mt ch thi tin x l if extern C phong trng h p file header c bin dich theo ki u C++. i u nay ngn ch n trinh bin dich khoi cac li trung tn cua cac ham C ++ v cho php cc th vin lin kt ng co th c s du ng bi ca cac chng trinh C va C++. i m vao va i m thoat cua th vin (Entry and Exit Point) Hm DllMain c gi n khi th vin lin kt ng ln u tin c nap vo b nh thc hin v khi no kt thuc nhim vu (bi loai khoi b nh ). Tham s u tin cua ham DllMain la handle ti instance cua th vi n. N u nh th vi n co s du ng cac tai nguyn oi hoi mt handle instance (ch ng ha n nh cac h p thoa i ), chung ta nn lu lai hInstance vo m t bi n toan cu c . Tham s cu i cung cua ham DllMain c d tr danh cho h t h ng s dung. Tham s fdwReason co th la m t trong 4 gi tri ch ra tai sao Windows lai gi ti hm DllMain. Trong cac mu c ti p theo chung ta nn nh r ng m t chng trinh n co th c

81

Bi ging mn hc: L p trinh Windows


nap nhiu ln v chay ng thi t rn Windows. Mi l n chng trinh c na p no c xem nh la m t ti n trinh (process) ring re. Gi tri cua tham s fdwReason bng DLL _PROCESS_ATTACH chi ra r ng th vi n lin k t ng a c anh xa vao vung ia chi cua m t ti n trinh . y la m t u m i cho php th vin thc hin bt c khi tao no oi hoi c phuc vu cho cc yu cu tip theo cua tin trnh. Cc khi tao kiu ny co th l cp pht b nh chng han . Trong thi gian ti n trnh ang chay , DllMain c go i vi m t tham s DLL _PROCESS_ATTACH chi m t l n trong ca thi gian t n ta i cua process o . B t c m t ti n trinh nao khac s du ng cung file DLL se go i n ham DllMain vi m t gia tri tham s DLL_PROCESS_ATTACH. N u nh vi c khi ta o la thanh cng DllMain se tra v m t gia tri khac 0, gi tri tr v l 0 s lm cho Windows khng chay chng trnh. N u gia tri cua fdwReason b ng DLL _PROCESS_DETACH thi co ngha l chng trnh khng cn file DLL na , v y l mt c hi th vin thc hin cc cng vic dn dep cua no . Trn cac h i u hanh 32 bit cua Windows i u nay khng thc s c n thi t nhng la m t thoi quen l p trnh tt. Tng t khi ham DllMain c go i vi m t gia tri tham s la DLL_THREAD_ATTACH thi co nghia la m t ti n trinh s du ng th vi n a ta o ra m t lu ng (thread) mi. Khi lu ng k t thuc Windows la i go i ti ham DllMain vi tham s la DLL_THREAD_DETACH. Cng co th xy ra trng hp Windows thc hin li gi ti hm DllMain vi gi tri cua tham s fdwReason bng DLL _THREAD_DETACH ma khng thc hi n li go i vi gia tri DLL _THREAD_ATTACH trc o n u nh th vi n lin k t ng c g n vi m t ti n trinh sau khi lu ng a c ta o ra. Lu ng vn t n ta i khi ham DllMain c go i n vi tham s DLL_THREAD_DETACH. No thm ch co th gi cc thng ip trong tin tr nh. Nhng cc lung khng nn s dung hm PostMessage () v lung co th kt thuc trc khi thng i p n ich. Chng trinh test th vi n lin k t ng la m t chng trinh n gian va la m t Project khac (thu c loa i Win 32 Application). Chung ta co th cc file cua 2 Project vao cung mt th muc hoc ring r trong 2 th mu c. Trong qua trinh dich chng trinh file simpledll .dll va simpledll .lib se c sinh ra trc, file simpledll .lib se c t ng lin k t vi chng trinh th nghi m va file simpledll.dll se c na p vao b nh khi chng trinh cha y . C n chu y la chng trinh usedll.exe khng cha ma cua ham s du ng trong th vi n , m cua hm ch c nap vo b nh khi chng trinh cha y. Vi c include file simpledll .h cung gi ng nh chung ta include file windows .h, lin k t vi file simpledll .lib cung tng t nh lin k t vi file user 32.lib va lin k t vi file simpledll.dll cung gi ng nh chng trinh lin k t vi file user32.dll. M c du chung ta x p m t file DLL la m t m r ng cua Windows nhng no cung la m t m r ng cua chng trinh ng du ng cua chung ta . T t ca nhng gi file DLL thc hi n u la thay m t cho ng du ng s du ng no . Ch ng ha n t t ca cac thao tac c p phat b nh c ki m sot bi chng trnh . B t c ca s nao no ta o ra u s hu bi chng trinh va b t c file no c m cng c kim sot bi ch ng trinh. Nhi u chng trinh co th s du ng cung

82

Bi ging mn hc: L p trinh Windows


m t file dll ng thi, nhng Windows se ong vai tro la ch n ngn ch n cac can thi p ln nhau gia cac ng du ng nay . Nhi u ti n trinh co th chia se cung m t m t oa n ma trong m t th vi n lin k t ng . Tuy nhin d li u c s u ng bi m t th vi n DLL se la khac nhau vi cac ti n trinh khac nhau. Mi ti n trinh co m t khng gian ia chi d li u cua ring no cha cac d li u co th s du ng n bi file DLL . Chia se b nh gia cac ti n trinh oi hoi m t s ky thu t khac ma chung ta s bn ti trong phn tip theo. 7.4. Chia se b nh gia cac th vin lin k t ng Windows c l p cac ng du ng s du ng cung m t th vi n lin k t ng ng thi . Tuy nhin i khi y khng phai la m t la cho n thich h p . Chung ta co th mun vit mt th vi n DLL cha m t vung nh nao o co th c chia se bi nhi u n g du ng, ho c gia cac instance cua cung m t ng du ng. i u nay lin quan ti vi s du ng b nh chia se , hay chinh xc l mt file nh xa b nh (memory-mapped file). Chung ta s kho st mt chng trnh co tn l strprog (String Program ) v th vin c s du ng la strlib (string library). Strlib cha 3 hm m strprog co th gi ti . V mt trong s cac ham cua strlib se s du ng m t ham call-back c inh nghia trong strprog. Strlib la m t th vi n lin k t ng cha va lam vi c vi m t xu t i a 256 k t. Xu c chuy n thanh da ng ky t hoa va ki m soat trong vung b nh chia se cua strlib . Strprog co th s dung 3 hm cua th vin Strlib cng , xoa v nh n c t t ca cac xu hi n ta i t strlib. Chng trinh strprog co hai mu c menu la cho n la Enter va Delete cho phep ngi dung nhp cc xu thc hin vic cng v xoa cc xu . Strprog se in ra gia tri t t ca ca c xu hi n ang n m cha trong th vi n. Cc hm c inh ngha trong th vin Strlib gm co: EXPORT BOOL CALLBACK AddString (pStringIn) EXPORT BOOL CALLBACK DeleteString (pStringIn) EXPORT int CALLBACK GetStrings (pfnGetStrCallBack, pParam) Hm th nht s chuyn cc xu thnh dang k t hoa v thm vo danh sch cc xu cua th vin. Gi tri tr v cua hm l TRUE (khc 0) n u nh thanh cng va FALSE (0) n u nh xay ra li : ho c xu co dai b ng 0 ho c khng c p phat c b nh ho c a s du ng h t 256 xu cua b nh. Hm th hai s thc hin xoa bo mt xu khoi danh sch cc xu cua th vin nu khp v nu co nhiu xu khp th ch xu u tin bi xoa . K t qua tra v cua ham la TRUE n u xoa bo thnh cng v FALSE nu xu cn xoa co di bng 0 ho c khng tim th y. Hm th ba l hm s dung lit k cc xu ang co trong th vin , hm ny s dung m t tham s la m t ham cal l-back cha trong chng trinh s du ng ham . Hm ny phi c inh nghia trong chng trinh s du ng th vi n nh sau: EXPORT BOOL CALLBACK GetStrCallBack (PSTR pString, PVOID pParam) Tham s pfnGetStrCallBack cua ham GetString chi ti m t hm call-back. GetString co th go i ti ham GetStrCallBack mi l n cho mi gia tri cua m t xu cho ti khi ham nay tra v FALSE. GetString se tra v s l ng cac xu c truy n cho ham call -back. Bi n pParam s l mt con tro far ti d li u c ngi dung inh nghia .

83

Bi ging mn hc: L p trinh Windows


T t nhin y chung ta cung s du ng hai phin ban cho mi ham , ANSI va Unicode version. 7.5. Cc vn khc v th vin lin kt ng Ti a tng c p trong ph n u cu a chng nay la cac th vi n lin k t ng khng nh n cac thng i p . Tuy nhin m t th vi n lin k t ng co th go i ti ham GetMessage va PeekMessage. Cc thng ip m th vin ly v t hng i thng ip qua cc hm n y thc s la cac thng i p cua cac chng trinh go i ti cac ham cua th vi n . Noi chung th vi n lam vi c thay m c cho chng trinh go i no m t qui lu t chi ph i h u h t cac ham cua Windows ma m t th vi n co th go i ti. M t th vi n lin k t ng co th na p cac tai nguyn (ch ng ha n nh cac bi u t ng chng trinh, cc xu v cc nh bitmap) t file th vi n ho c t cac file cua chng trinh go i ti th vi n o . Cc hm nap ti nguy n oi hoi m t handle ti instance . N u nh th vi n s dung handle ti instance cua ring no ( c truy n cho th vi n qua vi c go i ti ham DllMain khi tao no ) th th vin co th nhn c cc ti nguyn t file ring c ua no. na p cac ti nguyn t chng trnh gi ti cc hm cua th vin , oi hoi handle ti instance cua chng trinh go i ham. Vi c khai bao cac lp ca s chng trinh va ta o ra ca s chng trinh trong m t th vi n oi hoi mt s thu thut . C cu truc lp ca s v hm CreateWindow hoc CreateWindowEx u oi hoi m t handle ti m t instance cua chng trinh . M c du chung ta co th s dung hande cua th vin trong vic tao ra cc l p ca s va ca s chng trinh, cc thng i p ca s vn i qua hang i thng i p cua chng trinh go i ti th vi n khi th vi n ta o ra ca s chng trinh . N u nh ba n c n phai ta o ra cac lp ca s va cac ca s chng trinh trong m t th vi n thi t t nh t la nn s du ng handle ti instance cua chng trnh gi ti hm th vin. V cc thng ip cho cc hp thoai modal c nhn bn ngoi vong lp thng ip cua chng trnh nn chun g ta co th ta o ra m t h p thoa i modal trong m t th vi n b ng cch gi ti hm DialogBox . Handle ti instance co th la cua th vi n ho c tham s hwndParent cua ham DialogBox co th t b ng NULL. Cc th vin khng co import Thay vi Windows thc hi n vi c lin k t ng khi chng trinh l n u tin c nap vo b nh chung ta co th lin kt mt chng trnh vi mt th vin khi chng trnh ang cha y. Ch ng ha n chung ta mu n go i ti ham Rectangle nh sau: Rectangle (hdc, xLeft, yTop, xRight, yBottom) ; i u nay se lam cho chng trinh c lin k t ti th vi n gdi 32.lib khi bin dich l y ia chi cua ham Rectangle. Chung ta co th gi ti hm Rectangle theo mt cch khc: typedef BOOL (WINAPI * PFNRECT) (HDC, int, int, int, int) ; khai bao hai bi n: HANDLE hLibrary ; PFNRECT pfnRectangle ; Ti p n go i ti cac ham LoadLibrary va GetProcAddress :

84

Bi ging mn hc: L p trinh Windows


hLibrary = LoadLibrary (TEXT ("GDI32.DLL")) pfnRectangle = (PFNPRECT) GetProcAddress (hLibrary, TEXT ("Rectangle")) V by gi co th gi ti hm Rectangle: pfnRectangle (hdc, xLeft, yTop, xRight, yBottom) ; FreeLibrary (hLibrary) ; M c du ky thu t s du ng th vi n lin k t ng theo ki u nay kh ng lam tng hi u qua s du ng cua ham Rectangle nhng no la i la m t cach hi u qua trong trng h p ma chung ta khng bi t tn cua th vi n cho ti khi chng trinh cha y (ch ng ha n i vi ham AlphaBlend ch ng ha n). oa n ma trn s du ng hai ham LoadLibrary va FreeLibrary . Windows ki m soat cac bi n m tham chi u ti t t ca cac module th vi n . Hm LoadLibrary s lm cho bin m tham chi u ti cac th vi n c na p tng ln 1. Bi n m tham chi u cng c tng ln khi Windows na p m t chng trinh co s du ng th vi n . FreeLibarary se lam cho bi n m nay gim i 1, trng h p m t instance cua m t chng trinh s du ng th vi n bi loa i khoi b nh bi n m tham chi u cng gim i 1 n vi. Khi bi n m tham chi u nay b ng 0 Windows se loai bo th vin khoi b nh v luc o th vin khng con cn thit na. Cc th vin chi cha ti nguyn B t c ham nay trong m t th vi n lin k t ng ma m t chng trinh trn Windows va cc th vin khc co th gi ti u phi c export . Tuy nhin m t th vi n lin k t ng co th khng nht thit phi cha bt c mt hm export no . V y cac th vi n o cha gi ? Cu tra li la cac tai nguyn. Ch ng ha n chung ta lam vi c trn m t ng du ng Windows c n m t s cac anh bitmap . Thng thng chung ta se li t k cac anh nay trong file kich ban tai nguyn va na p chung vao b nh vi ham LoadBitmap. Nhng co le chung ta mu n co m t s t p anh , mi t p cho m t phn giai cua man hinh hinh thng c s du ng vi Windows . Gii php kh d nht l cha cac t p anh khac nhau nay vao cac file khac nhau vi m t ngi dung chi c n ti m t t p cc nh ny trn a cng. V cc file ny c gi l cc file th vin ch cha ti nguyn . Hnh 21-5 cho chung ta th y cach thc ta o ra m t th vi n chi cha tai nguyn c go i l bitlib.dll cha 9 nh bitmap. File bitlib.rc cha t t ca cac anh nay va gan cho mi anh m t s . ta o ra file bitlib .dll chung ta c n co 9 nh co tn ln lt l bitmap 1.bmp, bitmap2.bmp, , bitmap9.bmp. Chung ta co th s d ung cc nh i km vi a CD cua quy n sach dung. Bi tp: Bi tp 1: Vit th vin DLL cha cc hm x l xu.

85

Bi ging mn hc: L p trinh Windows


Ti liu tham kho [1] L Hu a t. Lp trinh Windows. NXB Giao du c. [2] Charles Petzold. Programming Windows, fifth edition. Microsoft Press. 1998. [3] Johnson M. Hart. Windows System Programming Third Edition. Addison Wesley Professional. 2004.

86

Bi ging mn hc: L p trinh Windows


thi tham kho s 1: Bi s 1 Cho Dialog sau:

Bi t r ng cac ID cua cc control cua Dialog trn nh sau : cc ID cua cc Edit Text tng ng vi cac Static Text Canh a , Canh b , Canh c l n l t la : ID_CANHA, ID_CANHB, ID_CANHC, ID cua Static 1 l ID_KQKT, ID cua Static 2 l ID_DTCV, ID cua cac Button Kiem tra va Thoat la ID _KIEMTRA, ID_THOAT. Hy vit hm x l cho Dialog trn sau cho khi nh n vao nut Kiem tra thi chng trinh se ki m tra xem ba s nguyn c nh p va 3 Edit text tng ng co la 3 canh cua 1 tam giac hay khng , k t qua ki m tra c thng bao qua Static 1. Trong trng h p la 3 canh cua 1 tam giac hay tinh va hi n thi chu vi , di n tich cua tam gic qua Static 2 v khi ngi dung nhn vo nut Thoat s kt thuc Dialog. Bi s 2 a) Hy trnh by (a ra ) dang n gin nht cua mt hm x l thng ip ca s chnh trinh (hm Window Proc). b) Gi s chng trnh ch co mt muc menu Help , trong o co 2 muc menu con l Contents va About , hy vit hm x l thn g i p ca s chng trinh sao cho khi ngi dung cho n cac mu c trong menu Help chng trinh se hi n thi cac thng bao (hm Message Box) tng ng va khi ngi dung nh n chu t trai vao 1 vi tr trn mn hnh, hy in ra mt thng bao v to a chu t ta i vi tri o (hm TextOut). s 2: Bi s 1 Vi t ham x ly h p thoa i sau:

87

Bi ging mn hc: L p trinh Windows

Cc iu khin XA , YA, XB, YB, XC, YC la to a 3 inh trn m t ph ng to a (nguyn). Khi nh n nut Tinh chu vi hay tnh chu vi cua tam gic tao thnh bi 3 inh A, B, C va hi n thi ln IDC _KQ. Nh n Thoat thoat khoi h p thoa i va nh n Tinh dien tich se tnh din tch v hin thi nh trong phn tnh chu vi Bi s 2 a) Hy trnh by (a ra) dang n gin nht cua mt hm x l thng ip ca s ch o m t h p thoa i. b) Hy vit hm WndProc cho mt chng trnh co h thng menu gm 1 muc File , trong o co cac mu c con vi cac chc nng sau : Menu1, Menu2, khi ngi dung nhn vo cc muc ny ch cn a ra thng bo n gin , muc Exit thot khoi chng trnh. s 3: Bi s 1 Vi t ham x ly h p thoa i sau:

Cc iu khin XA , YA, XB, YB, XC, YC la to a 3 inh trn m t ph ng ta (nguyn). Khi nh n nut Tinh chu vi hay tinh chu vi cua tam giac ta o thanh bi 3 inh A, B, C va hi n thi ln IDC _KQ. Nh n Thoat thoat khoi h p thoa i va nh n Tinh dien tich se tnh din tch v hin thi nh trong ph n tinh chu vi

88

Bi ging mn hc: L p trinh Windows


Bi s 2 a) Hy trnh by (a ra) dang n gin nht cua mt hm x l thng ip ca s ch o m t h p thoa i. b) Hy vit hm WndProc cho mt chng trnh co h thng menu gm 1 muc File , trong o co cac mu c con vi cac chc nng sau : Menu1, Menu2, khi ngi dung nh n vo cc muc ny ch cn a ra thng bo n gin , muc Exit thot khoi chng trnh.

89

You might also like