You are on page 1of 361

VIN I HC M H NI

KHOA CNG NGH TIN HC

DNG THNG LONG

LP TRNH TRN WINDOWS VI MFC

NH XUT BN KHOA HC V K THUT

LI NI U
Ngnh sn xut phn mm ng vai tr rt quan trng trong lnh vc Cng ngh tin hc, nh cc vn ca cuc sng c gii quyt mt cch hiu qu. Thc t hin nay ang cn nhiu phn mm tin hc ng dng trong mi lnh vc ca cuc sng, do i hi nhiu hn na n lc ca cc cng ty phn mm, cc chuyn gia pht trin phn mm, c bit l cc k s lp trnh vin phn mm. Trong khu quan trng v mt nhiu nhn lc thc hin l giai on lp trnh. Giai on lp trnh s dng mt s phng php nh lp trnh cu trc, lp trnh theo hng i tng. Vi mi phng php chng ta c th s dng cc cng c thc hin gm cc ngn ng lp trnh, cc mi trng lp trnh v c bit l phi da trn mt nn tng ca kin trc h iu hnh ang s dng. Hn na, Windows l h iu hnh ca Microsoft c s dng hu ht trong cc my tnh v cc ng dng phi ly n lm phn nn khi thc hin, do cc phn mm hu ht c lp trnh chy trn h iu hnh Windows. gip cc sinh vin chuyn ngnh cng ngh tin hc, cc lp trnh vin nm bt c nhng vn c bn ca lp trnh trn Windows, ngn ng lp trnh C++ theo hng i tng hc tp v lm vic chng ti xin gii thiu cun sch "Lp trnh trn Windows vi MFC". Sch gm c 10 chng nh sau: Chng 1: Gii thiu phng php lp trnh trn Windows, s tng tc gia Windows v cc phn mm ng dng, cc khi nim lin quan. Qua s dng ngn ng C++ v b th vin MFC th hin cc kt qu trong ti liu ny. Chng 2: Trnh by c ch nh x thng ip, cch x l thng ip v mt s thng ip c bn. C ch xut d liu ln ca s. Chng 3: Cc ti nguyn ca chng trnh, cch to lp, s dng v x l thng ip tng ng bao gm thc n, hp thoi v cc iu khin trn , cc biu tng v hnh nh.

Chng 4: Trnh by c ch ha ca lp trnh trn Windows, cc lnh lm vic trn ng cnh thit b (Device Context - DC) v ca s o - Virtual Window. Chng 5: X l vn bn trn ca s, to v s dng cu trc phng ch, c ch cp nht thng tin trn ca s. Chng 6: Trnh by cc iu khin nng cao trong Windows, cc lp lm vic tng ng ca th vin MFC nh thanh cng c, trng thi, cy... Chng 7: Mt kin trc quan trng trong hu ht cc ng dng, l kin trc ti liu/quan st (document/view), i t cc khi nim c bn n cch lm vic trn ng dng. Chng 8: Trnh by c ch vo ra d liu vi cc thit b ngoi nh a, my in. Chng 9: Mt trong nhng c tnh quan trng nht trn Windows l phng php lp trnh a tuyn c trnh by trong chng ny. Chng 10: Cch to v s dng th vin lin kt ng - DLL, mt thnh phn khng th thiu trong hu ht cc ng dng ca Windows. Chng 11: Gii thiu cch tip cn lp trnh theo kiu client/server, cc khi nim lin quan, cch to cc ActiveX v lp trnh trn n. Trong mi chng u c v d minh ha cho cc vn c trnh by, cc v d c chy th v cho kt qu tt. Cui mi chng c cc bi tp cho bn c c th tham kho v t kim tra cc kin thc cng nh tng thm k nng lp trnh. Tc gi mong nhn c nhng ng gp ca cc bn c. Mi kin xin gi v a ch: lduongthang@yahoo.com hoc Dng Thng Long, Khoa Cng ngh Tin hc - Vin i hc M H Ni.

H Ni ngy 14 thng 02 nm 2006

Tc gi

Chng 1 TNG QUAN V LP TRNH WINDOWS


1.1. Gii thiu v h iu hnh Windows
Windows l mt h iu hnh ang c s dng hu ht cc my tnh trn th gii, l mt sn phm ca hng phn mm ni ting Microsoft. Windows c pht trin t MS-DOS, trong m rng nhiu c tnh quan trng nh giao din, cch lm vic, s h tr i vi cc thit b ngoi vi, Sau y l mt s c tnh c cp nhm gip c gi hiu hn v mi trng Windows, cc hot ng, cc thnh phn, s tng tc gia Windows vi ng dng, t lp trnh s d dng hn.

1.1.1. c trng ca Windows


- Mi trng giao din ha Nh chng ta bit h iu hnh Windows cung cp giao din ha, nn mi thnh phn giao din trn mn hnh u di dng hnh nh to cho ngi s dng cm gic thn thin v trc quan hn. Cc ng dng trn Windows cng c xy dng trn c s giao din ha m Windows cung cp. V vy mt phn rt ln cc chng trnh ng dng l cung cp c ch giao din ha ny. - Tnh a nhim H iu hnh Windows cho php ti mt thi im c th thc hin c nhiu cng vic khc nhau trn my tnh, mi cng vic gi l mt task. Thc cht ca tnh a nhim l khai thc ti a tc x l nhanh ca CPU trn my tnh, c th minh ha theo m hnh gm 3 task nh sau:

- H tr qun l hu ht cc thit b ngoi vi. - H tr kt ni mng. - Tng thch vi cc ng dng ca DOS. Khi thc hin mt chng trnh trn DOS th Windows s to ra mt mi trng DOS gi lp chy. V vy hu ht cc chng trnh trn DOS s thc hin c trn Windows.

1.1.2. Cc thnh phn giao din trn Windows


Trn Windows cc ng dng rt thn thin vi ngi dng, bi giao din ha trc quan, kt hp vi thit b chut thao tc d dng. Do vy chng trnh trn Windows thng rt ln song ch yu l cung cp cc giao din cho ngi dng. Cc thnh phn giao din chnh nh sau: - Desktop Model Ging nh bn lm vic ca chng ta, trn s c nhng thnh phn ca chng ta lm vic v nhng ci chng ta ang lm vic. Bao gm cc biu tng, cc ca s chng trnh,... C th ni thnh phn ny l mt ca s ln nht, cha ton b cc thnh phn khc v ni th hin ca mi ng dng.

- Mouse Chut c s dng cho hu ht cc thao tc iu khin, la chn v v. Tuy nhin chng ta c th dng bn phm thay th, nhng l iu vi phm ti nguyn tc thit k c bn ca Windows. - Icon v bitmap Chng ta thy rng mt bc tranh ng gi vi hng ngn t - a picture is worth a thousand words. Icon l mt bc tranh thu nh din t cho mt thnh phn no ca cc ng dng trn Windows, bitmap l mt nh dng hnh nh m t lu gi cho cc icon. Icon c s dng chuyn ti thng tin nhanh chng, trc quan v n gin ti ngi dng. - Windows L cc ca s, ni din ra mi s tng tc gia ngi dng vi chng trnh ng dng. - Menu, Toolbar, Status bar L cc thnh phn trn ca s, h tr v cung cp cho ngi dng nhng chc nng cn thit mc n gin nht c th, thng bo ti ngi dng trng thi ang lm vic. - Dialog box L mt ca s dng hp thoi cho php ngi dng tng tc vi chng trnh, nh nhp d liu, xem thng tin, ...

1.1.3. Cc khi nim c bn


- Process Process (tin trnh) l qu trnh thc hin mt chng trnh t khi khi ng cho n khi kt thc. Windows cho php thc hin nhiu chng trnh cng mt lc, tc l s c nhiu process cng chy trn my. C th hiu mi task (cng vic thc hin) s tng ng vi mt process, tuy nhin c nhng process c to ra t nhng process khc.

- Thread Thread (lung) l mt n v thc hin no trong chng trnh, nh vy trong mt process c t nht mt thread v c th c nhiu. iu ny cho php chng ta xy dng cc chng trnh vi nhiu tc v cng thc hin, mi tc v tng ng vi mt lung.

Thread c to ra t mt process no , thm ch c th c to ra bi mt thread khc v n c th kt thc sau process, hoc kt thc ti thi im bt k (nh trn hnh v). - Cc kiu d liu c bn Cng nh trong ngn ng C, cc kiu d liu chun u c s dng trn Windows bao gm:
Tn ki u int, long, unsigned float, double char ngha S nguyn S th c K t

Mi thnh phn v i tng trong chng trnh u qun l bng cc s nh danh (Handle Identify), thng l s nguyn khng du 32 bt. Chng ta c mt s kiu lu cc nh danh nh sau:
Tn ki u WINAPI HANDLE HINSTANCE ngha Ki u s d ng khai bo chng trnh Gi tr nh danh cc ti nguyn S hi u nh danh ti n trnh ang ch y

HWND BYTE WORD LONG UINT BOOL LPSTR LPCSTR LRESULT LPARAM WPARAM LPVOID CALLBACK HDC HFONT HICON HFILE HMENU HPEN HBRUSH HBITMAP

S hi u nh danh m t c a s S nguyn 8 bt khng d u S nguyn 16 bt khng d u S nguyn 32 bt c d u S nguyn 32 bt khng d u S nguyn c gi tr TRUE ho c FALSE Con tr t i xu 1 k t H ng con tr t i 1 xu k t Ki u tr v c a cc hm Ki u nh ngha tham s c a cc hm d ng long

Ki u nh ngha tham s c a hm d ng word Con tr khng ki u S d ng trong khai bo hm g i ng c S hi u nh danh ng c nh thi t b nh danh phng ch nh danh bi u t ng nh danh t p tin nh danh th c n nh danh nt bt v nh danh ki u n n t nh danh nh bitmap cc ti li u khc.

Cn r t nhi u ki u c th tham kh o

1.2. Lp trnh trn Windows


1.2.1. Giao din li gi (call-based interface)
- Th vin API (Application Programming Interface) Lp trnh trn Windows phi s dng giao din li gi truy nhp ti h thng (call-based interface). chnh l mt tp rt ln cc hm c xy dng bi h thng v thc hin cc tc v c bn trn h iu hnh, nh ng k b nh, xut d liu ra mn hnh, to ca s,... Cc hm ny lp nn mt th vin API (Application Programming Interface). Mt chng trnh

ng dng s gi cc hm API ny thc hin cc chc nng, thao tc mong mun, qua s giao tip c vi Windows. C th minh ha bng s sau:

- Th vin GDI (Graphic Device Interface) Trong th vin lp trnh API c mt nhm cc hm chuyn x l ha gi l GDI, cc hm ny s cung cp cho ngi lp trnh lm vic vi cc thit b ha mt cch d dng v c lp vi cc thit b . - Th vin lin kt ng DLL (Dynamic Link Library) Th vin API cha mt lng rt ln cc hm cung cp cho ngi lp trnh, khi lng m lnh trong chng trnh ch yu l cc x l ha v vy s rt ln, c cc on m b lp. Do Windows cung cp cho chng ta mt c ch lin kt chng trnh, gi l th vin lin kt ng (Dynamic Link Libraries - DLL). Th vin lin kt ng s c lu gi mt tp m lnh c lp vi chng trnh, s c lin kt vi chng trnh trong khi thc hin, do lm cho m lnh ca cc chng trnh s nh hn. Tuy nhin cc chng trnh ny khi thc hin i hi phi c th vin DLL tng ng. Th vin API c cung cp sn trong windows, tc l sau khi ci t windows s c lun th vin ny. API tn ti di dng th vin lin kt ng. Chi tit v phn th vin lin kt ng s c trnh by chi tit phn cui.

1.2.2. S tng tc gia chng trnh vi Windows


- Khi nim v thng ip Lp trnh trn Windows c bn l vic x l cc thng ip (messages), cc thng ip ny c sinh ra bi ngi dng tc ng ln chng trnh, bi h thng yu cu chng trnh hoc ngay bn thn chng trnh t sinh ra. Mi thng ip l mt s nguyn 32 bt khng du v c gn vi mt s kin, mt tnh hung hay mt thao tc no , do vy chng ta phi nhn bit c x l cho ph hp. Vic nhn bit ny thng qua cc tham s ca hm ca s v cc macro c cung cp bi th vin API. - C ch pht sinh, nhn v chuyn pht thng ip trn Windows i vi h iu hnh MS-DOS, ngi lp trnh phi gi cc chc nng ca DOS thc hin yu cu thng qua cc ngt (interrupt), DOS s khng t gi chng trnh ca chng ta. iu ny hon ton khc vi Windows, mt chng trnh lun trong trng thi ch cc thng ip (message) ca mnh c gi n t Windows v khi nhn c thng ip th chng trnh phi thc hin yu cu tng ng. Chng ta c th minh ha s tng tc bng s sau:

H iu hnh DOS cung cp cho chng ta cc chng trnh phc v ngt vi cc hm, cc chc nng tng tc vi h iu hnh v lm vic vi cc thit b. Cc chng trnh ngt ny ch mc ti thiu, do chng ta phi xy dng hu ht cc th tc cn thit khi lp trnh.

10

i vi Windows th cc chc nng c gi trong th vin API v cu ni gia h thng vi chng trnh ng dng l cc thng ip. Hn na chng trnh trn DOS l ch ng thc hin cc cng vic, cn trn Windows hon ton b ng, chng trnh ch c thc hin khi c thng ip gi ti. - Cc loi thng ip v mt s thng ip c bn C hai loi thng ip, loi c nh ngha bi h thng v loi c nh ngha bi ngi lp trnh cung cp giao din cho ngi dng, gi tt l thng ip h thng v thng ip ngi dng. Cc thng ip chun ca h thng thng nh ngha di dng cc tn hng c ch WM (Windows Message) u. Sau y l bng mt s thng ip chun c bn:
WM_CHAR WM_LBUTTONUP WM_CREATE WM_CLOSE WM_TIMER WM_NOTIFY WM_KEYDOWN WM_PAINT WM_MOVE WM_KEYDOWN WM_MOUSEMOVE WM_RBUTTONDOWN WM_VSCROLL WM_HSCROLL WM_KEYPRESS WM_COMMAND WM_DESTROY WM_CREATE WM_KEYUP WM_QUIT ...

Cn thng ip ngi dng c th nh ngha qua tn hng hoc dng trc tip s nguyn, cc thng ip ny ch yu nh ngha cho cc thnh phn giao din nh thc n, cc iu khin trn hp thoi hoc ca s.

1.2.3. Lp trnh trn Windows


- Cc thnh phn c bn ca chng trnh trn Windows Theo kin trc da vo thng ip ca Windows, tt c cc chng trnh u c cu trc cc thnh phn chung nh nhau. Trong ngn ng C chng ta phi lp trnh tng minh cc thnh phn chung ny trong chng trnh. Tuy nhin vi lp trnh C++ c mt s phn s do c ch t ng sinh ra bi mi trng lp trnh (Visual C++), v vy ngi lp trnh gim bt c cng sc vit m lnh v chng trnh tr nn sc tch, r rng hn.

11

D sao chng ta cng phi xem xt cc thnh phn c bn ca mt chng trnh trn Windows l g? N bao gm 4 thnh phn sau: WinMain() L hm chnh ca chng trnh, khi chy chng trnh trn my th u tin h thng s gi thc hin hm ny. Hm ny s c khai bo nh sau:
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,

int nCmdShow );

Hai tham s u hInstance v hPreInstance c kiu HINSTANCE xc nh s hiu process tng ng mi ln thc hin chng trnh v s hiu ca ln ang thc hin k trc , tham s th lpCmdLine c kiu LPSTR xc nh tham s dng lnh khi khi ng chng trnh, cui cng l tham s nCmdShow c kiu int xc nh ch ca s chng trnh khi khi ng. Trong lp trnh C chng ta phi khai bo v xy dng hm ny nhng trong C++ chng s khng phi lm vic ny. C th ni hm ny l li vo (entry point) u tin ca chng trnh, sau mi hot ng s do Windows qun l v iu khin. Hm ca s - Window Function L hm rt c bit s c gn vi cc ca s trn Windows, hm ny s do my t gi khi h thng mun chuyn thng ip ti ca s tng ng. Ngi lp trnh phi xy dng hm ny thc hin x l cc thng ip mong mun. Khai bo ca hm nh sau:
LRESULT CALLBACK tn_hm( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );

Mi ca s tn ti trn Windows phi c mt hm tng ng nhn v x l thng ip, tham s kiu HWND xc nh s hiu ca s cha thng ip nhn c, th 2 kiu UINT xc nh tn thng ip, hai tham s cn li kiu WPARAM v LPARAM cha cc thng tin lin quan n thng ip.
12

Trong lp trnh C++ chng ta s khng phi khai bo v xy dng hm ca s ny. Vng lp thng ip - Message Loop S c thc hin trong hm chnh ca chng trnh (hm WinMain) sau khi to v thit lp hin th ca s chng trnh. Vng lp ny s thc hin nhn tt c cc thng ip ng vi tin trnh ca chng trnh v s gi n cc ca s tng ng. Vng lp ny c thc hin nh sau:
MSG msg; while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); }

Trong hm GetMessage() nhn tt c cc thng ip lin quan n chng trnh, thng ip nhn c lu tham s msg. Sau phn tch, lm mn thng ip bng lnh TranslateMessage() v chuyn pht ti cc hm ca s tng ng bng lnh DispatchMessage(). Vng lp ny s kt thc khi hm GetMessage() tr v gi tr FALSE, tng ng vi thng ip nhn c trong msg l WM_QUIT, ngc li tr v TRUE. - Phng php lp trnh C++ trn Windows Lp trnh C++ hay lp trnh hng i tng, ch yu xy dng cc lp s dng k tha t cc lp ca th vin MFC (Microsoft Foundation Classes). Do vy cc bn hy nm vng k thut lp trnh hng i tng trc khi thc hin theo cch ny. Cc lp trong th vin MFC c m rng t th vin cc lp ca ngn ng C++, bao gm cc cu trc c s c s dng to cc ng dng trn Windows. Mt khung ng dng c thit k trong th vin MFC chnh l

13

to chng trnh trn Windows, n nh ngha cu trc mt ng dng v cha cc cng vic thng thng cho ng dng. Th vin lp trnh MFC s bao gi hu ht cc hm ca th vin API theo hnh thc 1-1, tc l mi hm c trong API s c gi thnh mt hm thnh vin trong mt lp no ca MFC. Tuy nhin khi lp trnh MFC chng ta c th s dng cc hm API nh bnh thng. S phn lp th vin API, GDI, DLL v MFC minh ha nh sau:

- Cc thun li khi lp trnh MFC MFC to ra mt khung ng dng v t chng ta c th xy dng mt ng dng trn Windows. Cung cp th vin ln cc m ngun c th s dng li, c th tch hp vi lp trnh hng th tc. MFC rt ngn thi gian pht trin chng trnh, cc h tr khng lm gim tnh mm do ca chng trnh, h tr cc cng ngh pht trin nh ActiveX hay lp trnh Internet. MFC h tr truy nhp c s d liu qua th vin OLE DB v ADO, h tr lp trnh mng qua Windows Sockets. Cho php to cc thnh phn giao din trong chng trnh nh trang thuc tnh, hp thoi in, thanh cng c, Khi tip cn lp trnh theo cch ny, chng ta phi xy dng cc lp mi tha k t cc lp c sn ca MFC. Vic x l cc thng ip s c nh x v nh ngha thnh cc phng thc ca lp tng ng.
14

- Th vin cc lp trong MFC Th vin cc lp MFC c cung cp bi tp khai bo afxwin.h do phi thc hin lnh np th vin ny vo trong chng trnh nh sau:
#include <afxwin.h>

Cc lp c bn trong th vin MFC c gii thiu bng sau:


Tn l p CWinApp CFrameWnd CView CFile CDocument CDialog CSplitterWnd CFileDialog CFontDialog CPrintDialog CColorDialog CToolBarCtrl CStatusBarCtrl CTreeCtrl CMonthCalCtrl CDC CSingleDocTemplate ngha L p ng d ng L p khung c a s L p quan st ti li u L p lm vi c v i t p tin trn a L p ti li u L p h p tho i L p chia c a s thnh nhi u ph n L p h p tho i file L p h p tho i phng ch L p h p tho i in n L p h p tho i ch n mu L p i u khi n thanh cng c L p i u khi n thanh tr ng thi L p i u khi n hi n th d ng cy L p i u khi n ch n thng L p ng c nh thi t b L p m u ti li u n ng d ng

Ch : Cc lp c tn vi tin t l ch C (Class), cc t trong tn lp c ch ci u vit hoa, cn li vit thng. - Cc hm thnh vin L cc hm m ngi lp trnh lun phi gi t cc i tng ca lp trong th vin MFC, cc hm thnh vin ny hu ht l bao gi cc hm ca th vin API do vic chuyn t lp trnh C sang lp trnh MFC tng i d, tuy nhin cch lp trnh MFC gim bt rt nhiu cng sc cho ngi lp trnh.
15

- Cc hm ton cc Ngoi cc hm thnh vin cc lp MFC, th vin afxwin.h cn cung cp mt s hm ton cc (khng thuc lp ca th vin MFC) v tn cc hm ny ging vi cc hm API nhng c thm tin t l Afx (application framework). V d hm AfxMessageBox() hin th hp thng bo cho ngi dng. Lp trnh C++ theo MFC ch yu xy dng cc lp, cc thnh vin trong lp. s dng cc hm API chng ta phi s dng ton t phm vi du 4 chm (::) vit, v d vit GetDC(); s khc vi ::GetDC(); (2) cch vit (1) c ngha l gi hm thnh vin trong lp ang x l, cn cch (2) s gi hm ca th vin API. (1)

1.3. Xy dng khung chng trnh MFC


1.3.1. Lp ng dng - CWinApp
Lp CWinApp l lp xy dng mt chng trnh ng dng trong th vin MFC, v vy chng ta phi k tha t lp ny to mt lp ng dng mi. Cch nh ngha lp ng dng l:
class { /* khai bo cc thnh vin mi trong lp */ public: BOOL InitInstance( ); tn_lp_ng_dng : public CWinApp

/* khai bo cc thnh vin mi trong lp */ };

16

Trong chng ta phi np chng hm InitInstance() khi to mt ng dng nh to ca s v mt s tc v khc, nu thc hin khi to ng dng thnh cng th tr v gi tr TRUE tip tc, hoc ngc li tr v gi tr FALSE bo cho my bit chng trnh s dng khng chy tip. V d khai bo mt lp ng dng n gin sau:
class CMyApp : public CWinApp { public: BOOL InitInstance( ); };

- Mt s thnh vin d liu ca lp CWinApp:


Tn thnh vin ngha

m_pszAppName m_hInstance m_lpCmdLine m_nCmdShow m_pActiveWnd m_pszExeName m_pszProfileName m_pMainWnd m_hThread m_nThreadID m_pszRegistryKey m_pszProfileName

Tn ca chng trnh ng dng S hiu process ca chng trnh ang chy Chui k t cha tham s dng lnh Trng thi ca s ng dng Ca s chnh ca ng dng Tn tp EXE ca chng trnh Tn tp INI ca ng dng S hiu ca s chnh ca chng trnh S hiu nh danh lung hin thi S hiu ca lung hin thi Xu k t cha ng k trong h thng Xu k t cha tn cc tham s chng trnh

Cc thnh vin hm ca lp CWinApp s c trnh by c th trong tng phn ca ti liu ny.

1.3.2. Lp CFrameWnd
Lp ny cho php to cc ca s cho chng trnh v chng ta k tha t lp ny xy dng lp ca s ng dng mi theo mong mun.

17

Cch khai bo lp ca s l:
class { /* cc khai bo thm cho lp ca s mi ny */ public: /* khai bo hm to mc nh to ca s */ tn-lp-ca-s (); }; tn-lp-ca-s : public CFrameWnd

V d khai bo mt lp ca s:
class CMyWin : public CFrameWnd { public: CMyWin(); DECLARE_MESSAGE_MAP() };

Trong hm to ca lp ca s ny chng ta phi thc hin to mt ca s mi bng lnh:


BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );

Trong : + lpszClassName: tn lp ca s c ng k hoc l tn chun c sn trong h thng, lp ca s quy nh cc thuc tnh chung cho ca s. Tuy nhin chng ta c th t l NULL th my s dng cc thuc tnh mc nh cho ca s, + lpszWindowName: tn ca s, l chui k t xut hin trn thanh tiu ca s, + cc tham s cn li c th khng cn v my s ly gi tr mc nh. V d vit lnh cho hm to ca lp CMyWin thc hin to mt ca s:
18

CMyWin :: CMyWin() { Create( NULL , "Chng trnh n gi n nh t" ); }

Cng vic to mt i tng ca s t lp ca s ny cho chng trnh s c thc hin trong hm InitInstance() ca lp CWinApp trn, sau s hin th ca s v v li ni dung trn ca s. V d vit lnh cho hm InitInstance() ca lp CMyApp trn to mt ca s:
BOOL CMyApp :: InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); }

Lnh th nht to i tng ca s gn vo thnh vin m_pMainWnd ca lp ng dng CWinApp, tip theo hin th ca s c to bng lnh ShowWindow() vi tham s l trng thi ca s, c th ly t thnh vin m_nCmdShow ca lp ng dng hoc ly mt trong cc gi tr sau:
Tn gi tr SW_SHOWNORMAL SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_RESTORE SW_HIDE SW_SHOW ngha Ch bnh th ng Phng nh t Thu nh t Khi ph c ch tr c Lm n c a s Hi n l i c a s sau khi n

Tuy nhin trong mt chng trnh khng cn to ca s th chng ta khng phi xy dng lp ca s ny. Khi trong hm InitInstance() ca lp CWinApp khng thc hin to ca s, m ch thc hin nhng tc v khc theo yu cu.

19

1.3.3. Hp thng bo trong MFC


Hp thng bo l mt ca s c bit ch thng bo vi ngi s dng v tnh trng thc hin ca chng trnh. Trn hp thng bo c tiu ca hp, dng thng bo trn hp v biu tng ca hp. MFC cung cp mt hm API hin th hp thng bo c c php nh sau:
int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );

Trong : + lpszText: l dng ch thng bo, + nType: kiu hp thng bo, xc nh cc nt lnh trn v biu tng. C th s dng ton t hoc bit (|) kt hp mt gi tr kiu nt lnh vi mt gi tr biu tng trong cc gi tr sau:
Gi tr Quy nh nt l nh trn h p thng bo MB_ABORTRETRYIGNORE MB_HELP MB_OK MB_OKCANCEL MB_RETRYCANCEL MB_YESNO MB_YESNOCANCEL Quy nh bi u t ng trn h p thng bo MB_ICONEXCLAMATION, MB_ICONWARNING MB_ICONINFORMATION, MB_ICONASTERISK MB_ICONQUESTION Bi u t ng h i MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND C 3 nt l nh l abort, retry v ignore C nt l nh tr gip Nt l nh Ok Nt l nh Ok v Cancel Nt l nh Retry v Cancel Nt l nh Yes v No Nt l nh Yes, No v Cancel ngha

Bi u t ng c nh bo

Bi u t ng thng tin

Bi u t ng d ng

20

Tuy nhin chng ta c th b qua tham s nType v nIDHelp v my s ly mc nh, khi trn hp thoi s c nt lnh Ok v biu tng chm than. Hm hin th hp thng bo ny s tr v gi tr nt lnh m ngi s dng chn ng vi cc gi tr sau:
Gi tr IDYES IDNO IDCANCEL IDOK IDIGNORE IDRETRY IDABORT ngha Ch n nt Yes Ch n No Ch n Cancel Ch n Ok Ch n Ignore Ch n Retry Ch n Abort

1.4. Cch t chc chng trnh MFC


Trong mi trng pht trin chng trnh ca Visual C++ gm c hai b dch song song l b dch m lnh (code compilation) v b dch ti nguyn (resource compilation). S t chc v hot ng ca cc thnh phn trong chng trnh c minh ha bi hnh v trang sau. Trong chng trnh c cc tp m lnh (source files) c kt hp vi cc khai bo th vin ca MFC (MFC header files) dch thnh tp OBJ files, tp cha nh ngha ti nguyn (resource script files) c dch thnh tp RES files. Trong qu trnh dch ny c kt hp bi tp tin nh ngha hng resource.h, cui cng hai tp RES v OBJ c lin kt cng vi cc th vin m lnh ca Windows v MFC thnh tp tin thi hnh EXE files. Mt chng trnh gm c cc phn sau: - Khai bo cc lp Phn ny thng c thc hin trong mt tp c phn m rng l *.h, cha mi khai bo lp cho ng dng. - Vit lnh cho cc hm thnh vin ca cc lp khai bo

21

Phn ny thc hin trong mt tp m lnh *.cpp v trong tp ny ch cn np tp khai bo trn bng cu lnh #include "*.h". - Cc phn khc Ngoi ra cn c cc phn khc sau ny s nh ngha sau, thng l cc ti nguyn ca chng trnh. Ch : Trong tp m lnh chng ta phi to ra mt i tng ng dng duy nht t lp k tha ca CWinApp.

Nu chng trnh nh th chng ta c th khai bo cc lp v vit lnh vo trong mt tp m lnh *.cpp.

22

Nu chng trnh ln th chng ta c th tch mi khai bo v vit lnh cho mt lp thnh hai tp *.h v *.cpp ring bit. - Cch to mt chng trnh trn Visual C++ Bc 1: Khi ng chng trnh Microsoft Visual C++ Chn th t cc chc nng sau: Start Studio 6.0 Microsoft Visual C++. Programs Microsoft Visual

Giao din ca VisualC++ gm 3 phn c bn: phn hin th cc thnh phn ca mt d n (project) chng trnh, phn lp trnh cho mt tp tin m lnh v phn kt qu dch chng trnh. Bc 2: To mt chng trnh mi, mi chng trnh gi l mt Project Vo th t cc chc nng [File] [New] chn th [Projects] chn mc [Win32 Application] nhp tn chng trnh vo [Project name] v chn [Ok] tip theo chn mc [An empty project] v chn [Finish]. Chng ta c th chn chc nng [MFC AppWizard (exe)] to chng trnh theo cc bc hng dn, tuy nhin c nhiu phn my t to ra khng kim sot c. n gin chng ta lp trnh t u, t n gin n phc tp. Bc 3: To mt tp tin m lnh lp trnh Chn chc nng [File] [New] chn th [Files] chn mc [C++ Source File] nhp tn tp vo [File name] chn [Ok]. Nu cn to tp khai bo chng ta chn mc [C/C++ Header File] trong th [Files]. Bc 4: Nhp chng trnh vo ca s ca tp va to bc 3. Bc 5: t chng trnh ch c s dng th vin MFC Chn [Project] Static Library" [Settings...] chn [Ok]. chn th [General] chn "Use MFC in

Bc 6: Bm "Ctrl+F5" dch v chy th chng trnh.

23

Sau khi dch kt qu hin th phn ca s di cng, nu c li chng ta bm p chut vo thng bo li my s t ng chuyn n dng b li v sa li.

V d 1.1
Lp mt chng trnh ch hin ln mt thng bo no khi thc hin.
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; CMyApp theApp; BOOL CMyApp::InitInstance() { AfxMessageBox("Chuong trinh don gian nhat, chi co thong bao"); return true; }

Kt qu khi chy chng trnh l:

V d 1.2
Lp chng trnh n gin to mt ca s v hin ln khi chy chng trnh.
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public:

24

CMyWin(); }; CMyApp theApp; /* Hm kh i t o ng d ng */ BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow( m_nCmdShow ); m_pMainWnd->UpdateWindow(); return true; } /* Hm t o c a l p c a s */ CMyWin::CMyWin() { Create(NULL, "Chuong trinh tao cua so don gian"); }

Trong hm InitInstance() chng ta thc hin lnh to i tng ca s t lp CMyWin v gn vo thnh phn m_pMainWnd ca i tng lp ng dng, sau hin th ca s v v li ca s . Trng thi hin th ca ca s l thnh phn m_nCmdShow ca lp ng dng. Kt qu chng trnh s l:

25

1.5. Bi tp
Bi tp 1.1
Lp chng trnh hin thng bo c hai nt lnh Yes v No cng vi biu tng hi.

Bi tp 1.2
Lp chng trnh to mt ca s v hin th vi kch thc to nht.

Bi tp 1.3
Lp chng trnh to mt ca s v hin th ch thu nh.

Bi tp 1.4
Lp chng trnh to hai ca s, mt ca s c tiu l Bi tp 1.4 v ca s cn li tiu l h tn ca bn. Hin th hai ca s ln mn hnh ch bnh thng.

Bi tp 1.5
Lp chng trnh hin 3 thng bo vi ni v biu tng nh sau: Thng bo 1: Lp trnh Windows vi biu tng cnh bo v hai nt lnh Ok, Cancel. Thng bo 2: Th vin MFC vi biu tng thng tin v hai nt lnh Yes, No. Thng bo 3: Lp trnh Windows vi MFC vi biu tng dng v ba nt lnh Yes, No, Retry.

Bi tp 1.6
Lp chng trnh to 15 ca s ging nhau vi tiu bt k v hin chng ln mn hnh ch bnh thng.

26

Chng 2 NH X X L THNG IP
2.1. C ch nh x x l thng ip
Nh cp trong chng trc, lp trnh trn Windows l phi x l cc thng ip c gi n chng trnh t Windows v thc hin cc cng vic tng ng trong chng trnh, c th l trong cc hm ca s (windowfunction) hoc hm hp thoi (dialog-function). i vi lp trnh MFC chng ta phi thc hin nh x cc thng ip thnh cc thnh vin hm (methods-phng thc) ca mt lp ca s hay hp thoi no , v khng c hm ca s trong MFC. nh x thng ip thc cht l s kt hp gia mt s hiu thng ip (message ID) vi mt hm thnh vin ca lp. Thng ip thng c chia lm 2 nhm, gm nhm cc thng ip c cung cp bi Windows, nhm cc thng ip l cc lnh t thc n, i tng iu khin ca chng trnh, ng vi 2 nhm ny th cch thc nh x s khc nhau. Mt lp nu c x l thng ip th cui cng ca khai bo lp phi c macro DECLARE_MESSAGE_MAP(), mi thng ip c nh x ti mt hm thnh vin ca lp v hm phi c khai bo dng afx_msg. Khai bo lp c x l thng ip theo mu sau:
class { tn_lp_dn_xut : public tn_lp_c_s /* cc khai bo khc ca lp */ /* khai bo hm thnh vin thc hin nh x thng ip */ DECLARE_MESSAGE_MAP() };

27

Trong phn khai bo thnh vin hm chng ta phi thc hin khai bo cc hm s x l thng ip tng ng theo mu sau:
afx_msg tn-kiu-d-liu tn-hm( cc-tham-s-nu-c );

Sau y l mt s thng ip v mu khai bo hm thnh vin trong lp tng ng:


Tn thng i p WM_CHAR WM_PAINT WM_LBUTTONDOWN WM_DESTROY WM_TIMER WM_VSCROLL WM_SIZING WM_SIZE WM_MOVE WM_MOVING WM_MOUSEMOVE WM_MOUSEWHEEL WM_KEYDOWN WM_CLOSE WM_KEYUP WM_LBUTTONDOWN WM_RBUTTONDOWN WM_LBUTTONUP WM_RBUTTONUP C php hm x l thng i p afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); afx_msg void OnPaint( ); afx_msg void OnLButtonDown( UINT nFlags, CPoint point ); afx_msg void OnDestroy( ); afx_msg void OnTimer( UINT nIDEvent ); afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ); afx_msg void OnSizing( UINT nSide, LPRECT lpRect ); afx_msg void OnSize( UINT nType, int cx, int cy ); afx_msg void OnMove( int x, int y ); afx_msg void OnMoving( UINT nSide, LPRECT lpRect ); afx_msg void OnMouseMove( UINT nFlags, CPoint point ); afx_msg LRESULT OnRegisteredMouseWheel( WPARAM wParam, LPARAM lParam ); afx_msg void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ); afx_msg void OnClose( ); afx_msg void OnKeyUp(UINT c, UINT r, UINT f); afx_msg void OnLButtonDown( UINT f, CPoint p); afx_msg void OnRButtonDown( UINT f, CPoint p); afx_msg void OnLButtonUp( UINT f, CPoint p); afx_msg void OnRButtonUp( UINT f, CPoint p);

Chi tit cc tham s cho tng hm thnh vin s c trnh by phn sau. Cc thng ip do chng ta nh ngha th vic nh x ti cc hm thnh vin do chng ta t t tn, khng theo quy nh ca Windows.

28

C php thc hin nh x cc thng ip ti cc hm thnh vin ca mt lp:


BEGIN_MESSAGE_MAP ( tn_lp_dn_xut , tn_lp_c_s ) /*nh x thng ip c nh ngha bi Windows*/ ON_WM_tn_thng_ip_ca_windows( ) /*nh x thng ip nh ngha bi chng ta*/ ON_COMMAND( s_hiu_thng_ip , tn_hm_thc_hin ) END_MESSAGE_MAP( )

Chng ta phi thc hin nh x trc khi vit lnh cho cc thnh vin ca lp.

V d 2.1
Lp trnh to mt ca s v thc hin nh x x l thng ip bn phm hin thng bo sau mi ln g phm.
#include<afxwin.h> /* ====== Khai bo l p ng d ng ========= */ class CMyApp : public CWinApp { public: BOOL InitInstance(); }; /* ====== Khai bo l p c a s ====== */ class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnChar(UINT kytu, UINT solan, UINT co); DECLARE_MESSAGE_MAP() }; /* ======= T o m t i t ng ng d ng ======== */ CMyApp theApp; /* == Vi t l nh cho phng th c kh i t o ng d ng == */ BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true;

29

} /* ==== nh x thng i p x l trong l p c a s ===== */ BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_CHAR() END_MESSAGE_MAP() /* ==== Vi t l nh cho cc phng th c trong l p c a s ===== */ CMyWin::CMyWin() { Create(NULL, "Chuong trinh tao cua so don gian"); } afx_msg void CMyWin::OnChar(UINT kytu, UINT solan, UINT co) { char s[200]; sprintf(s,"Ban vua go chu [%c]",kytu); AfxMessageBox(s); }

Trong v d trn c s dng hm sprintf() hin cc d liu vo mt chui k t, hm ny c c php ging vi lnh hin d liu ra mn hnh trong ngn ng C. Trong nh dng %c hin d liu di dng k t, gi tr m k t lu trong tham s kytu ca hm. Kt qu chng trnh sau khi chy v bm phm ch h s xut hin nh sau:

30

2.2. Ng cnh thit b v hin d liu ra ca s


2.2.1. Khi nim v ng cnh thit b
Ng cnh thit b (Device Context - DC) l mt cu trc m t cho giao din hin th ca ca s trn mn hnh, bao gm trnh iu khin thit b ca mn hnh v cc tham s nh phng ch, mu ch... do vy mi ca s s c mt DC tng ng. Minh ha bng hnh v sau:

Trn ca s s c h ta cho vic xc nh v tr d liu khi hin ra, ta ny c xc lp theo gc gc tri trn ca s v tng t tri sang phi theo chiu x, tng t trn xung theo chiu y.

31

Gc tri trn s c ta l (0,0) v tng cho n gc phi di. xc nh kch thc vng hin d liu trn ca s ta s dng hm sau:
void CWnd :: GetClientRect( LPRECT lpRect ) const;

Trong lpRect l a ch bin nh kiu cu trc RECT lu ta kch thc ca vng ca s bn trong. Cu trc RECT nh sau:
typedef { LONG left; LONG top; LONG right; LONG bottom; } RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; struct tagRECT

Trc khi chng trnh mun hin d liu ra ca s th phi ly DC tng ng ca ca s . Tip theo s dng cc lnh hin d liu, sau khi kt thc DC v ca s tng ng s khng c lin kt vi nhau na. Do vy nu mun hin tip ta phi thc hin t u. i vi lp trnh truyn thng ta phi s dng kiu HDC lu ng cnh thit b ly c bng cch s dng hm GetDC(). Tip theo hin d liu ra bng hm TextOut() v sau khi hin xong phi gii phng DC ly bng hm ReleaseDC(), bi v Windows s cung cp qun l mt s gii hn DC no trong chng trnh. Trong lp trnh MFC chng ta thc hin vic ny bng i tng lp CDC, cho nn cng vic tr nn d dng v thun tin hn rt nhiu.

2.2.2. Lp CDC v xut d liu ra ca s


Lp CDC (Class Device Context) cho php qun l ng cnh thit b ca s v thc hin cc thao tc hin d liu trn ca s . xc nh i tng lp CDC ca mt ca s ta s dng hm thnh vin sau ca lp CWnd:
CDC* CWnd :: GetDC( );

32

hm tr v kiu bin tr ca lp CDC. V lp CWnd l lp c s ca lp CFrameWnd nn chng ta c th s dng hm ny trong lp CFrameWnd cng nh cc lp dn xut t lp CWnd. Trong lp CDC c rt nhiu hm thnh vin hin d liu ra ca s v cc lnh v ha ln ca s, y ch gii thiu hm hin chui ra ca s cn nhng hm khc s trnh by chi tit phn sau. - Hm hin dng ch ln mn hnh
virtual BOOL int nCount ); CDC :: TextOut( int x, int y, LPCTSTR lpszString,

hoc
BOOL CDC :: TextOut( int x, int y, const CString& str );

Trong : + x,y l ta bt u ca dng ch cn hin ln ca s, + lpszString l chui k t cn hin, + nCount l di chui, + str l hng chui k t c kiu CString.

2.2.3. Thng ip WM_PAINT


Thng ip WM_PAINT c sinh ra v gi n ca s khi h thng cn chng trnh phi hin li cc d liu trn ca s, tc l khi c s thay i kch thc, khi chuyn i trng thi kch hot. Mi khi c s thay i trng thi ca s (kch thc, kch hot) th mi d liu trn ca s s b mt v do vy chng ta phi c c ch hin li nhng d liu . Chng ta x l thng ip WM_PAINT lm iu ny. Trong hm x l thng ip ny c th dng hm GetDC() ly ng cnh thit b ca s, tuy nhin thng thng s dng lnh BeginPaint() bt u hin d liu v sau khi hin xong dng lnh EndPaint() kt thc, c php 2 lnh l:
CDC* void BeginPaint( LPPAINTSTRUCT lpPaint ); EndPaint( LPPAINTSTRUCT lpPaint ); 33

Trong tham s lpPaint c kiu l mt cu trc PAINTSTRUCT lu gi cc thng tin v ca s s c hin li d liu v n c nh ngha nh sau:
typedef struct _PAINTSTRUCT { HDC hdc; BOOL fErase; RECT rcPaint; BOOL fRestore; BOOL fIncUpdate; BYTE rgbReserved[32]; } PAINTSTRUCT;

Trong : + hdc: lu s hiu ng cnh thit b ng vi ca s, + fErase: cho bit chng ta c phi v li nn ca s hay khng, + rcPaint: cho bit to kch thc ca khung ca s c hin th, + fRestore, fIncUpdate, rgbReserved: l cc tham s dnh ring cho h thng. Mu ca hm x l s kin cho thng ip WM_PAINT s c vit nh sau:
afx_msg { PAINTSTRUCT ps; void tn_lp_ca_s :: OnPaint()

CDC *dc = BeginPaint( &ps ); ... vit cc lnh thc hin in d liu ln ca s qua dc ... EndPaint( &ps ); }

34

C ch hin d liu ln ca s s thc hin qua thng ip WM_PAINT ny, mi d liu hin ln ca s s c lu trong cc thnh vin d liu ca ca s, mi s thay i d liu trn ca s phi thc hin cc thnh vin d liu ny, sau mi hin ln ca s qua thng ip WM_PAINT. Tuy nhin nu khi no cn hin li d liu, tc l pht sinh thng ip WM_PAINT chng ta s dng hm sau:
void InvalidateRect ( LPCRECT lpRect, BOOL bErase = TRUE );

Trong lpRect l cu trc kiu RECT nh trnh by trn cha ta kch thc ca s cn thc hin cho thng ip WM_PAINT, tuy nhin c th t tham s ny bng NULL nu thc hin trn c ca s hin thi. Tham s th hai bErase cho bit c xa v v li nn ca s hay khng, mc nh c gi tr TRUE.

V d 2.2
Lp trnh to mt ca s hin ln dng ch "Khoa Cong nghe Tin hoc chao cac ban".
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow);

35

m_pMainWnd->UpdateWindow(); return true; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_PAINT() END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL, "Chuong trinh vi du 2 - Chapter 02"); } afx_msg void CMyWin::OnPaint() { PAINTSTRUCT ps; CDC *dc = BeginPaint(&ps); dc->TextOut(10,10,"Khoa Cong nghe Tin hoc chao cac ban"); EndPaint(&ps); }

Kt qu trn mn hnh khi chy chng trnh s l:

2.3. X l cc thng ip c bn
2.3.1. Thng ip bn phm
Thng ip bn phm c sinh ra khi c s tc ng ca ngi s dng ln bn phm v h thng s gi mt thng ip ti chng trnh ng vi vic g phm . Thng ip bn phm bao gm cc tn c nh ngha nh sau: WM_CHAR

36

Thng ip ny c sinh ra khi g mt phm khng phi l phm h thng iu khin nh F1,F2,Ctrl,Alt,... n bao gm cc phm ch, phm s, cc phm du. Hm x l thng ip ny c khai bo theo mu sau,
afx_msg nFlags ); void OnChar( UINT nChar, UINT nRepCnt, UINT

Trong : + nChar: l m phm c g, + nRepCnt: l s ln c g, + nFlags: l trng thi ca cc phm khc, trong nu bt 29 bng 1 th phm Alt ang c gi, ngc li s bng 0. WM_KEYDOWN, WM_KEYUP Thng ip WM_KEYDOWN c sinh ra khi bt u nhn phm xung, thng ip WM_KEYUP c sinh ra sau khi nh phm v thc hin cho mi phm trn bn phm, hm x l thng ip khai bo theo mu sau:
afx_msg void UINT nFlags ); OnKeyDown( UINT nChar, UINT nRepCnt,

v
afx_msg nFlags ); void OnKeyUp( UINT nChar, UINT nRepCnt, UINT

Trong cc tham s nh hm OnChar() trn nhng ch c tham s trng thi nFlags s c trnh by chi tit nh sau:
Cc bt 0-7 8 9-10 11-12 13 14,15 ngha M m r ng cc phm B ng 1 n u l phm ch c nng ho c phm s m r ng Khng s d ng S d ng b i Windows B ng 1 n u phm Alt c gi v ng c l i Tr ng thi tr c c a phm

37

V d 2.3
Lp chng trnh to ca s v hin ln ca s cc ch c g t bn phm, mi ch cch nhau 20 pixels, mi hng c 10 ch v cng cch nhau 20 pixels.
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_CHAR() END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL, "Chuong trinh vi du 3 - Chapter 02"); } afx_msg void CMyWin::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { static int x=10,y=10;

38

CDC *dc = GetDC(); char s[5]; sprintf(s,"%c",nChar); dc->TextOut(x,y,s); x += 20; if ( x>200 ) { x=10; y +=20; } }

Trong hm OnChar() ca v d trn s dng hai bin x v y kiu bin tnh, tc l gi tr ca n c lu gi cho nhng ln thc hin tip theo ca hm. Kt qu trn mn hnh sau khi g mt s phm s l:

Tuy nhin khi g y ca s th n s khng t ng trt ln nh cc ca s vn bn, m cng vic ny chng ta phi t lp trnh. Hn na nu ta thay i kch thc hay trng thi ca s th cc ch s b mt, nu mun hin li c ta phi thc hin trong hm OnPaint() nh trnh by.

V d 2.4
Lp trnh to ca s v hin ln trng thi cc phm chc nng m rng khi g mt phm ch no . Chng ta s x l thng ip WM_KEYDOWN trong lp ca s v hin ln cc thng bo m phm c bm. Ni dung chng trnh s l:
39

#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_KEYDOWN() END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL, "Chuong trinh vi du 4 - Chapter 02"); } afx_msg void CMyWin::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { char s[200]; CDC *dc=GetDC(); sprintf(s,"Phim ALT %s ",((nFlags>>13)&1==1)?"dang duoc an":"khong duoc an"); dc->TextOut(10,10,s); sprintf(s,"Ma phim mo rong duoc bam la %d ",nFlags&0xFF); dc->TextOut(10,30,s); sprintf(s,"Ma ASCII cua phim duoc bam la %d ",nChar); dc->TextOut(10,50,s); }

40

Kt qu chy chng trnh sau khi bm phm ch A s xut hin nh sau, ng thi gi phm Alt:

2.3.2. Thng ip chut


Thng ip chut c sinh ra khi c s tc ng ca ngi s dng ln thit b chut, cc tn thng ip lin quan n chut l:
Tn thng i p WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK WM_MOUSEMOVE WM_MOUSEWHEEL ngha B m nt tri chu t xu ng Nh nt tri chu t B m p nt tri chu t B m nt ph i chu t xu ng Nh nt ph i chu t B m p nt ph i chu t B m nt gi a chu t xu ng Nh nt gi a chu t B m p nt gi a chu t Di chuy n con chu t Tc ng ln nt cu n c a chu t

Cc mu hm khai bo cho nh x x l cc thng ip lin quan n chut nh sau:


afx_msg afx_msg void void OnLButtonDown( UINT nFlgs, OnLButtonUp( UINT nFlgs, CPoint pt ); CPoint pt );

41

afx_msg afx_msg afx_msg afx_msg afx_msg afx_msg afx_msg afx_msg

void void void void void void void void

OnLButtonDblClk( UINT nFlgs, OnRButtonDown( UINT nFlgs, OnRButtonUp( UINT nFlgs,

CPoint pt ); CPoint pt );

CPoint pt ); CPoint pt ); CPoint pt );

OnRButtonDblClk( UINT nFlgs, OnMButtonDown( UINT nFlgs, OnMButtonUp( UINT nFlgs,

CPoint pt ); CPoint pt );

OnMButtonDblClk( UINT nFlgs, OnMouseMove( UINT nFlgs, OnMouseWheel( UINT nFlgs,

CPoint pt ); short zDelta,

afx_msg BOOL CPoint pt );

Trong : + UINT nFlgs: l gi tr cc bt c trng thi ca cc phm iu khin, bao gm cc gi tr c nh ngha nh sau:
MK_CONTROL MK_SHIFT MK_LBUTTON MK_RBUTTON MK_MBUTTON Phm Ctrl c gi Phm Shift c gi Phm tri chu t c gi Phm ph i chu t c gi Phm gi a chu t c gi

Nu c phm hoc nt chut c gi khi c thng ip chut th tham s nFlgs s cha cc gi tr c tng ng nh bng trn. + CPoint pt : l v tr ca chut khi pht sinh thng ip, lp CPoint cha mt im 2 ta (x l honh , y l tung ) bao gi t cu trc POINT nh sau:
typedef struct tagPOINT { LONG x; LONG y; } POINT;

Ta ny ca chut s tng ng vi gc gc tri trn ca ca s, chiu x tng t tri sang phi, chiu y tng t trn xung di.
42

+ short zDelta: xc nh khong cun nt chut, nu l s m c ngha l cun ln; nu s dng c ngha l cun xung. Thng thng gi tr ca zDelta l 120 pixels.

V d 2.5
Lp trnh to ca s v hin thng bo tng ng vi trng thi chut ti cc v tr ca chut trn ca s. Trong chng trnh ny chng ta x l cc thng ip v chut gm WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_RBUTTONDBLCLK, WM_MOUSEWHEEL. Ni dung chng trnh nh sau:
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnLButtonDown( UINT nFlgs, CPoint pt ); afx_msg void OnLButtonUp( UINT nFlgs, CPoint pt ); afx_msg void OnLButtonDblClk( UINT nFlgs, CPoint pt ); afx_msg void OnRButtonDown( UINT nFlgs, CPoint pt ); afx_msg void OnRButtonUp( UINT nFlgs, CPoint pt ); afx_msg void OnRButtonDblClk( UINT nFlgs, CPoint pt ); afx_msg void OnMouseMove( UINT nFlgs, CPoint pt ); afx_msg BOOL OnMouseWheel( UINT nFlgs, short zDelta, CPoint pt ); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true;

43

} BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_RBUTTONDBLCLK() ON_WM_MOUSEMOVE() ON_WM_MOUSEWHEEL() END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL, "Chuong trinh vi du 5 - Chapter 02"); } afx_msg void CMyWin::OnLButtonDown( UINT nFlgs, CPoint pt ) { CDC *dc=GetDC(); dc->TextOut(pt.x,pt.y,"Nut trai duoc bam "); } afx_msg void CMyWin::OnLButtonUp( UINT nFlgs, CPoint pt ) { CDC *dc=GetDC(); dc->TextOut(pt.x,pt.y,"Nut trai duoc nha "); } afx_msg void CMyWin::OnLButtonDblClk( UINT nFlgs, CPoint pt ) { CDC *dc=GetDC(); dc->TextOut(pt.x,pt.y,"Nut trai duoc bam dup "); } afx_msg void CMyWin::OnRButtonDown( UINT nFlgs, CPoint pt ) { CDC *dc=GetDC(); dc->TextOut(pt.x,pt.y,"Nut phai duoc bam "); } afx_msg void CMyWin::OnRButtonUp( UINT nFlgs, CPoint pt ) { CDC *dc=GetDC(); dc->TextOut(pt.x,pt.y,"Nut phai duoc nha "); } afx_msg void CMyWin::OnRButtonDblClk( UINT nFlgs, CPoint pt ) {

44

"); } afx_msg void CMyWin::OnMouseMove( UINT nFlgs, CPoint pt ) { CDC *dc=GetDC(); char s[200]; sprintf(s,"[x=%d,y=%d] ",pt.x,pt.y); dc->TextOut(1,5,s); } afx_msg BOOL CMyWin::OnMouseWheel( UINT nFlgs, short zDelta, CPoint pt ) { CDC *dc=GetDC(); char s[200]; sprintf(s,"Mouse Wheel with delta=%d",zDelta); dc->TextOut(pt.x,pt.y,s); return 1; }

CDC *dc=GetDC(); dc->TextOut(pt.x,pt.y,"Nut phai duoc bam dup

Kt qu chy chng trnh sau khi tc ng ln chut ta c:

2.3.3. Thng ip thi gian


Thng ip thi gian c sinh ra theo chu k thi gian v c gn vo mi ca s. Thng ip thi gian c tn l WM_TIMER, khong chu k thi gian do chng ta t v mi ca s c th c nhiu chu k thi gian ng vi cc thng ip thi gian khc nhau.

45

Mi chu k thi gian ng vi mt thng ip WM_TIMER s c h thng gi ti hng i thng ip v gi hm thi gian thc hin. t chu k thi gian trn mt ca s chng ta s dng hm thnh vin ca ca s c khai bo theo mu sau:
UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)( HWND, UINT, UINT, DWORD) );

Trong : + nIDEvent: l s hiu chu k thi gian s t cho ca s, + nElapse: l khong thi gian xc nh mt chu k tnh bng mili giy, + lpfnTimer: l a ch ca hm thi gian, hm ny s c gi thc hin mi mt chu k thi gian tri qua. C th t tham s ny l NULL. Hm t chu k ny s tr v s hiu ca chu k thi gian t thnh cng, nu khng thnh cng hm tr v s 0. x l thng ip WM_TIMER ng vi chu k thi gian t, chng ta s dng mu khai bo hm nh x thng ip nh sau:
afx_msg void OnTimer( UINT nIDEvent );

Trong nIDEvent l s hiu chu k thi gian ng vi thng ip WM_TIMER, s hiu ny c c khi t chu k bng lnh SetTimer() trn. Nu mun hy b chu k thi gian t trn ca s chng ta s dng lnh sau:
BOOL KillTimer( int nIDEvent );

Trong nIDEvent l s hiu chu k thi gian cn hy b. Nu my tm thy chu k ng vi s hiu th s hy b v tr v gi tr TRUE, ngc li tr v gi tr FALSE khi khng tm thy chu k tng ng vi s hiu a vo.

V d 2.6
Lp trnh to ca s v t chu k thi gian x l thng ip WM_TIMER hin ln ca s thi gian ca h thng.

46

Trong chng trnh cn ly thi gian hin ti ca h thng nn chng ta s dng lp CTime, trong c hm thnh vin tnh GetCurrentTime() xc nh thi gian ca my v tr v i tng kiu CTime.
static CTime PASCAL CTime :: GetCurrentTime( );

Lp CTime c mt s hm thnh vin c bn nh sau:


Hm thnh vin GetHour() GetMinute() GetSecond() GetYear() GetMonth() GetDay() GetDayOfWeek() ngha Cho gi Cho pht Cho giy Cho nm Cho thng Cho ngy Cho ngy trong tu n (1=ch nh t, 2=th hai,...)

Ni dung chng trnh nh sau:


#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); ~CMyWin(); afx_msg void OnTimer( UINT nIDEvent ); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true; }

47

BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_TIMER() END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL, "Chuong trinh vi du 6 - Chapter 02"); //SetTimer SetTimer(117,1000,NULL); } CMyWin::~CMyWin() { //KillTimer KillTimer(117); } afx_msg void CMyWin::OnTimer( UINT nIDEvent ) { CDC *dc=GetDC(); char s[200]; CTime t = CTime::GetCurrentTime(); sprintf(s,"Thoi gian la = [%2d:%2d:%2d] ", t.GetHour(), t.GetMinute(), t.GetSecond()); dc->TextOut(5,5,s); }

Kt qu chy chng trnh s l:

Chng ta thc hin t chu k thi gian trong hm to ca lp ca s, sau lnh to ca s v hy b chu k trong hm hy ca ca s tng ng.

2.3.4. Mt s thng ip khc


- Thng ip ng ca s WM_CLOSE Mi ln ng ca s thot khi chng trnh my s pht sinh thng ip WM_CLOSE, ngi lp trnh c th x l thng ip ny nu mun thc hin mt s thao tc trc khi thot khi chng trnh. V d nh hi ngi dng c mun thot hay khng, hay lu gi mt s d liu ca chng trnh ln a.

48

Mu hm khai bo cho x l thng ip ny nh sau:


afx_msg void OnClose( );

Trong ci t cho hm OnClose() ny s gi n hm hy b ca s DestroyWindow(), nu chng ta khng mun ng ca s th khng gi hm ny. Khi ca s b xa b my s pht sinh thng ip WM_DESTROY v mu hm x l thng ip ny nh sau:
afx_msg void OnDestroy( );

Ch : Nu c x l thng ip WM_CLOSE th trong hm OnClose() ca lp ca s phi gi n hm OnClose() ca lp c s thc hin ng ca s nu cn. - Thng ip kch hot ca s WM_ACTIVATE Thng ip ny c sinh ra khi mt ca s c kch hot ln (do ang b che khut bi mt ca s khc, do ang ch thu nh). Mu hm nh x x l thng ip ny khai bo nh sau:
afx_msg void OnActivate( UINT nState, pWndOther, BOOL bMinimized ); CWnd*

Trong tham s u (nState) kiu UINT quy nh trng thi kch hot c th l WA_ACTIVE, WA_CLICKACTIVE hoc WA_INACTIVE, tham s th 2 (pWndOther) kiu CWnd xc nh ca s ang c kch hot v tham s cui (nMinimized) cho bit ca s c ch thu nh hay khng tng ng gi tr TRUE hoc FALSE. - Thng ip thay i v tr v kch thc ca s WM_MOVING, WM_MOVE, WM_SIZING, WM_SIZE Cc thng ip ny c sinh ra khi mt ca s b dch chuyn, b thay i kch thc. S kin ang din ra hoc din ra tng ng thng ip c hu t ING (ng t dng Verb+ing) hoc khng. Mu hm nh x x l thng ip c khai bo tng ng nh sau:
afx_msg void OnMoving( UINT nSide, LPRECT lpRect ); afx_msg void OnMove( int x, int y ); 49

afx_msg void OnSizing( UINT nSide, LPRECT lpRect ); afx_msg void OnSize( UINT nType, int cx, int cy );

Trong tham s nSide quy nh cnh ca ca s ang b thay i, lpRect xc nh kch thc v v tr mi. Hoc tham s x, y cho bit v tr mi, cx v cy cho bit kch thc mi sau khi thay i. Chng ta thy rng vic x l thng ip thng thng thc hin trong lp ca s, dn xut t CFrameWnd, t CWnd. Hu ht cc hm nh x ny c nh ngha trong lp CWnd, by gi chng ta "vit " li cc hm nh x thng ip.

V d 2.7
Lp trnh to ca s v x l thng ip WM_CLOSE hi ngi dng c chc chn hay khng, m rng t v d 2.6 (x l thi gian). Trong chng trnh ny chng ta s thc hin t chu k thi gian trong hm InitInstance() qua thnh vin m_pMainWnd ca lp ng dng, thc hin hy chu k thi gian trong hm OnDestroy() ca lp ca s. Ni dung chng trnh nh sau:
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnDestroy(); afx_msg void OnClose(); afx_msg void OnTimer(UINT nIDEvent); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BOOL CMyApp::InitInstance() {

50

m_pMainWnd = new CMyWin; //SetTimer if (m_pMainWnd->SetTimer(117,1000,NULL)!=117) { MessageBox(NULL,"Khong dat duoc chu ky thoi gian","Loi chuong trinh",MB_OK); return FALSE; } m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_DESTROY() ON_WM_CLOSE() ON_WM_TIMER() END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL, "Chuong trinh vi du 7 - Chapter 02"); } afx_msg void CMyWin::OnDestroy() { KillTimer(117); } afx_msg void CMyWin::OnClose() { if (MessageBox("Co chac chan khong?","Dong cua so",MB_YESNO | MB_ICONQUESTION)==IDYES) { DestroyWindow(); } } afx_msg void CMyWin::OnTimer(UINT nIDEvent) { CDC *dc=GetDC(); char s[200]; CTime t = CTime::GetCurrentTime(); sprintf(s,"Thoi gian la = [%2d:%2d:%2d] ", t.GetHour(), t.GetMinute(), t.GetSecond() ); dc->TextOut(5,5,s); }

51

Kt qu sau khi chy chng trnh s nh sau: nu chn ng ca s s xut hin thng bo hi c chc chn khng, nu chn Yes th s ng ca s bng lnh gi DetroyWindow().

2.4. Bi tp
Bi tp 2.1
Lp trnh to ca s v x l thng ip WM_PAINT hin ln bng cu chng ca 5.

Bi tp 2.2
Lp trnh to ca s v x l thng ip WM_PAINT hin ln bng ch ci ting Anh in hoa v in thng.

Bi tp 2.3
Lp trnh to ca s v x l thng ip WM_CHAR nhn cc k t lu vo mt bin xu k t, sau hin cc k t nhn c ln ca s trong thng ip WM_PAINT.

Bi tp 2.4
Lp trnh to ca s v x l thng ip WM_KEYUP dch chuyn mt k t c m 0xB1 trn ca s theo cc phm mi tn (ln, xung, tri, phi). Mi ln dch chuyn mt khong 2 pixels, nu ta ca k t vt ra ngoi ca s th khng dch, ta bt u ca k t l gia ca s.

52

Bi tp 2.5
Lp trnh to ca s v x l thng ip WM_MOUSEMOVE hin ta ca chut ln gia tm ca s, x l thng ip WM_RBUTTONDOWN ng ca s nu cn.

Bi tp 2.6
Lp trnh to ca s v x l thng ip WM_TIMER hin ln gia tm ca s thng tin v th, ngy, thng, nm hin ti ca my, thng tin v gi, pht v giy.

Bi tp 2.7
Lp trnh to ca s v x l thng ip WM_MOUSEMOVE tnh di con ng ca chut dch chuyn qua trn ca s, di c tnh bng n v pixel. Mi ln dch s c tnh thm v hin ln ca s di .

Bi tp 2.8
Lp trnh to ca s v x l cc thng ip hc kim tra tc g phm. Ti mi thi im nh (chng hn c mi 0.5 giy) th my s hin mt ch ci bt k ti mt v tr bt k trn ca s, nu ngi s dng g ng k t th tnh 3 im, g sai tr 1 im v hin kt qu chi ln gc tri trn ca s. Chng trnh cho php thay i tc chi bng cch bm cc phm F1 v F2 tng hoc gim tc .

Bi tp 2.9
Lp trnh to ca s v x l cc thng ip hc hin ca s bng cc ch s t 0 n 9. Nu ngi s dng g mt phm s th ch s tng ng trn ca s s b mt v thay th bng mt ch s ngu nhin no , qu trnh s tip tc cho n khi cc ch s ging nhau th thng bo ngi chi thng cuc.

Bi tp 2.10
Lp trnh to ca s v x l cc thng ip to mt ng h m ngc, ln thi gian s c xc nh bng cch bm chut tri s tng, bm chut phi s gim v hin ln ln ca s. Nu bm phm Enter s bt u m ngc cho n ht v ng ca s.
53

Chng 3 TO V S DNG TI NGUYN


3.1. Khi nim v ti nguyn
Ti nguyn (resources) l cc i tng gm biu tng, hnh nh, thc n, thanh cng c, c to ra cung cp cho chng trnh. Trong Visual C++ cung cp mt cng c to cc ti nguyn v gn chng vi chng trnh. Cc ti nguyn c lu trong mt tp tin c phn m rng l *.rc, sau y chng ti s gii thiu mt s ti nguyn hay s dng.

3.2. Thc n lnh (menu) v lp CMenu


Menu l mt th hin giao din cha cc chc nng ca chng trnh, mi thi im mt ca s c th c gn vi mt menu. thc hin vic gn kt mt menu vi ca s ta lm cc bc sau: Bc 1: nh ngha cc mc trn menu trong tp ti nguyn. Bc 2: Np menu khi chng trnh to ca s cha n. Bc 3: X l cc la chn trn menu. Tp ti nguyn (resource file) y l tp cha tt c cc nh ngha ti nguyn trong chng trnh, tp c phn m rng l *.RC. Tn tp ti nguyn phi trng vi tn tp chng trnh, v d chng ta c tn tp chng trnh l main.cpp th tp ti nguyn i km phi l main.rc.

3.2.1. To thc n v gn vo ca s
Menu c th c nhiu cp, menu ngang pha trn cng ca s, menu dc ca mi mc menu ngang gi l popup. Do vic nh ngha theo cu trc sau:
54

nh ngha menu ngang:


Tn_menu { _nh ngha cc mc chn ngang y_ } MENU [ty chn]

- Phn ty chn y cho bit mc chn trng thi no v cc tham s ca n, gm c:


Ty ch n DISCARDABLE FIXED LOADONCALL MOVEABLE PRELOAD ngha Menu c th xa kh i b nh n u khng dng n a Menu s c c nh trong vng nh Menu s c n p khi s d ng Menu c th di chuy n trong b nh Menu c n p khi chng trnh b t u th c hi n

Mi mc c th l mc chn hoc l mt thc n dc (popup), do vy ta c nh ngha mc chn theo mu sau:


MENUITEM chn] Tn_mc_chn_ngang, s_hiu_mc_chn [,ty

Trong : + tn mc chn ngang: l ni dung vn bn s hin ln mc chn, + s hiu mc chn: nh danh mc chn cho vic x l thng ip la chn sau ny. nh ngha mt popup theo mu sau:
POPUP { _nh ngha cc mc chn dc y_ } Tn_popup [,tu chn]

Trong ty chn ca mc chn ngang hoc popup cho bit cc tham s lin quan n mc chn, bao gm:
55

Tu ch n CHECKED GRAYED HELP INACTIVE MENUBARBREAK MENUBREAK SEPARATOR

ngha M t d u hi u s c nh tn m c ch n

M c ch n c mu xm v khng th ch n C th lin k t v i m c ch n tr gip M c ch n b t t kch ho t T o m t m c ch n trn m t phn cch m i Gi ng MENUBARBREAK nhng khng c ng phn cch T o m t ng phn cch gi a cc m c ch n

nh ngha cc mc chn dc cng nh cc mc chn ngang trn. Ch : Thng thng cc s hiu ca mc chn thc n c nh ngha qua cc tn hng cho d qun l v x l trong chng trnh, cc nh ngha ny c thc hin trong tp khai bo RESOURCE.H ca chng trnh.

V d 3.1
nh ngha mt thc n theo mu sau:

- Tp cha khai bo cc tn s hiu mc chn thc n resource.h nh sau:


/* ======= t p resource.h ========*/ #define IDR_MYMENU 101 #define IDM_FILE_NEW 40001 #define IDM_FILE_OPEN 40002 #define IDM_FILE_EXIT 40003

Trong tp ny chng ta nh ngha s hiu thc n, s hiu cc mc chn thc n qua cc tn. - Tp cha nh ngha thc n *.rc nh sau:

56

#include "resource.h" IDR_MYMENU MENU DISCARDABLE BEGIN POPUP "File" BEGIN MENUITEM "New", IDM_FILE_NEW MENUITEM "Open", IDM_FILE_OPEN MENUITEM SEPARATOR MENUITEM "Exit", IDM_FILE_EXIT, CHECKED END MENUITEM "Edit", IDM_EDIT MENUITEM "Tools", IDM_TOOLS MENUITEM "Help", IDM_HELP END

Trong nh ngha ny chng ta s dng cp t kha BEGIN v END thay th cho cp k t { v } bt u v kt thc qu trnh nh ngha cc mc chn thc n. Sau khi nh ngha xong thc n chng ta thc hin gn thc n vo ca s bng cch t tham s thc n vo lnh Create() trong hm to ca lp ca s.
Create( NULL, tiu__ca_s, WS_OVERLAPPEDWINDOW, rectDefault, NULL, s_hiu_thc_n );

Trong tham s cui cng xc nh s hiu thc n chnh l s hiu ca thc n khi nh ngha thc n v phi chuyn v dng chui bng cch s dng c ch p v kiu LPSTR, v d:
Create( NULL, Chng trnh v d, WS_OVERLAPPEDWINDOW, rectDefault, NULL, (LPSTR)IDR_MYMENU );

Tuy nhin c th thc hin gn thc n vo ca s bt k thi im no bng cch s dng i tng lp CMenu qun l v thc hin theo cc bc sau: Bc 1: To i tng t lp CMenu Bc 2: Np thc n t chng trnh vo i tng bng lnh sau:
BOOL CMenu :: LoadMenu( LPCTSTR lpszResourceName );

57

hoc:
BOOL CMenu :: LoadMenu( UINT nIDResource );

Trong lpszResourceName l tn ti nguyn thc n cn np vo my, hoc nIDResource l s hiu thc n. Bc 3: Gn thc n vi ca s bng lnh sau:
BOOL CWnd :: SetMenu( CMenu* pMenu );

V d 3.2
Lp chng trnh to ca s v gn thc n trn vi ca s c to ra. Chng ta thc hin gn thc n vo ca s trong lnh to ca s hm to ca lp, chng trnh s c vit nh sau:
/* T p ch a nh ngha cc h ng c a m c ch n resource.h */ #define IDR_MYMENU 101 #define IDM_FILE_NEW 40001 #define IDM_FILE_OPEN 40002 #define IDM_FILE_EXIT 40003 /* T p ch a nh ngha ti nguyn th c n main.rc */ #include "resource.h" IDR_MYMENU MENU DISCARDABLE BEGIN POPUP "File" BEGIN MENUITEM "New", IDM_FILE_NEW MENUITEM "Open", IDM_FILE_OPEN MENUITEM SEPARATOR MENUITEM "Exit", IDM_FILE_EXIT, CHECKED END MENUITEM "Edit", IDM_EDIT MENUITEM "Tools", IDM_TOOLS MENUITEM "Help", IDM_HELP END /* T p chng trnh chnh main.cpp c a v d ny */ #include<afxwin.h> #include "resource.h" class CMyApp : public CWinApp { public:

58

BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return true; } CMyWin::CMyWin() { Create( NULL, "Chuong trinh vi du 01 - Chapter 03", WS_OVERLAPPEDWINDOW, rectDefault, NULL, (LPSTR)IDR_MYMENU ); }

Kt qu khi chy chng trnh s c ca s nh sau:

Trong c mt s mc chn ang b m do chng ta cha x l thng ip chn chc nng trn thc n. Chng trnh ny s dng c ch gn thc n vo ca s bng tham s trong lnh to ca s Create().

59

3.2.2. X l thng ip la chn thc n


Thng ip la chn thc n s c my gi ti chng trnh qua thng ip WM_COMMAND, trong s gi km theo s hiu ca mc thc n (hoc chc nng) c chn. C th thc hin nh x x l thng ip chn thc n theo tng chc nng hoc theo nhm chc nng, cc bc thc hin nh sau: Bc 1: Khai bo v xy dng cc hm thnh vin x l cho thng ip chn thc n, hm ny c khai bo theo kiu afx_msg v tr v kiu void. Bc 2: S dng cc macro sau thc hin nh x x l thng ip chn thc n ti cc hm thnh vin ca lp ca s
ON_COMMAND( id, memberFxn );

Trong id l s hiu mc chn ca thc n cn nh x, memberFxn l tn hm thnh vin s x l la chn cho mc chn tng ng vi s hiu . Thc hin khai bo ny trong phn nh x thng ip ca lp bi cc macro BEGIN_MESSAGE_MAP v END_MESSAGE_MAP. Ch : Nu cn nh x theo nhm chc nng thnh mt hm th hm phi c mt tham s kiu UINT nhn s hiu chc nng khi la chn v s dng macro sau thc hin nh x:
ON_COMMAND_RANGE( id, idLast, memberFxn );

Trong id l s hiu chc nng u nhm, idLast l s hiu chc nng cui trong nhm, memberFxn l tn hm thnh vin s thc hin ng vi cc chc nng trong nhm c chn.

V d 3.3
Lp trnh to ca s c mt thc n nh v d 3.2, x l cc thng ip la chn trn thc n hin ln ca s cc thng bo ca chc nng c chn tng ng. Chng ta s dng i tng lp CMenu np thc n v t vo ca s trong hm to ca ca s tng ng.

60

/* T p ch a nh ngha tn cc ch c nng resource.h */ #define IDR_MYMENU 101 #define ID_CAPNHAT_NHAPMOI 40001 #define ID_CAPNHAT_SUACHUA 40002 #define ID_TIMKIEM_TIMTHEOTEN 40003 #define ID_TIMKIEM_TIMTHEOQUEQUAN 40004 #define ID_BAOCAO_BAOCAODOANHTHU 40005 #define ID_BAOCAO_BAOCAOLOINHUAN 40006 #define ID_HETHONG_TROGIUP 40007 #define ID_HETHONG_THOAT 40008 /* T p ch a nh ngha ti nguyn th c n main.rc */ #include resource.h IDR_MYMENU MENU DISCARDABLE BEGIN POPUP "Cap nhat" BEGIN MENUITEM "Nhap moi", ID_CAPNHAT_NHAPMOI MENUITEM "Sua chua", ID_CAPNHAT_SUACHUA END POPUP "Tim kiem" BEGIN MENUITEM "Tim theo ten", ID_TIMKIEM_TIMTHEOTEN MENUITEM "Tim theo que quan", ID_TIMKIEM_TIMTHEOQUEQUAN END POPUP "Bao cao" BEGIN MENUITEM "Bao cao doanh thu", ID_BAOCAO_BAOCAODOANHTHU MENUITEM "Bao cao loi nhuan", ID_BAOCAO_BAOCAOLOINHUAN END POPUP "He thong" BEGIN MENUITEM "Tro giup", ID_HETHONG_TROGIUP MENUITEM "Thoat", ID_HETHONG_THOAT END END /* T p ch a n i dung chng trnh chnh main.cpp */ #include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public:

61

BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnNhapmoi(); afx_msg void OnSuachua(); afx_msg void OnTimtheoten(); afx_msg void OnTimtheoquequan(); afx_msg void OnBaocaodoanhthu(); afx_msg void OnBaocaoloinhuan(); afx_msg void OnTrogiup(); afx_msg void OnThoat(); DECLARE_MESSAGE_MAP() }; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND( ID_CAPNHAT_NHAPMOI , OnNhapmoi ) ON_COMMAND( ID_CAPNHAT_SUACHUA , OnSuachua ) ON_COMMAND( ID_TIMKIEM_TIMTHEOTEN , OnTimtheoten ) ON_COMMAND( ID_TIMKIEM_TIMTHEOQUEQUAN , OnTimtheoquequan ) ON_COMMAND( ID_BAOCAO_BAOCAODOANHTHU , OnBaocaodoanhthu ) ON_COMMAND( ID_BAOCAO_BAOCAOLOINHUAN , OnBaocaoloinhuan ) ON_COMMAND( ID_HETHONG_TROGIUP , OnTrogiup ) ON_COMMAND( ID_HETHONG_THOAT , OnThoat ) END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL,"Chuong trinh vi du 03 - Chapter 03"); //Load & set menu for program CMenu *m = new CMenu; m->LoadMenu(IDR_MYMENU); SetMenu(m); m->DestroyMenu(); delete m; } afx_msg void CMyWin::OnNhapmoi()

62

{ CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc nhap moi } afx_msg void CMyWin::OnSuachua() { CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc sua chua ");

");

} afx_msg void CMyWin::OnTimtheoten() { CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc tim theo ten "); } afx_msg void CMyWin::OnTimtheoquequan() { CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc tim theo que quan "); } afx_msg void CMyWin::OnBaocaodoanhthu() { CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc bao cao doanh thu "); } afx_msg void CMyWin::OnBaocaoloinhuan() { CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc bao cao loi nhuan "); } afx_msg void CMyWin::OnTrogiup() { CDC *dc=GetDC(); dc->TextOut(10,50,"Ban da chon muc tro giup "); } afx_msg void CMyWin::OnThoat() { //Dong cua so & thoat khoi chuong trinh OnClose(); } CMyApp theApp;

63

Kt qu khi chy chng trnh v chn mt chc nng trn thc n:

3.2.3. S dng phm nng (accelerator key)


Mi chc nng trn thc n chng ta c th gn bng mt phm tt, khi thay th cho vic dng chut chn chc nng chng ta c th bm phm tt . lm iu ny trong chng trnh chng ta lm theo cc bc sau: Bc 1: nh ngha bng cc phm tt theo mu sau
tn_bng_phm_tt { ACCELERATORS tn_phm_1 , s_hiu_chc_nng_1 [ , kiu ] [ ty chn ] tn_phm_2 , s_hiu_chc_nng_2 [ , kiu ] [ ty chn ] tn_phm_3 , s_hiu_chc_nng_3 [ , kiu ] [ ty chn ] ... }

Trong tn_bng_phm_tt l tn ca mt hng s nguyn thng thng ging vi tn thc n nh ngha, tn_phm l k hiu cc phm tt cn t, c th m phm di dng ascii hoc m phm o. Nu l phm dng m ascii th tham s kiu l ASCII, cn nu s dng m phm o th kiu l VIRTKEY bao gm mt trong cc phm c trn bn phm hoc t hp phm bao gm:

64

K hi u tn phm 0, 1, ..., 9, A...Z VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN VK_F1, ..., VK_F12 VK_CONTROL, VK_ALT, VK_SHIFT v r t nhi u phm khc

ngha Cc phm s , phm ch , ... Cc phm mi tn Cc phm ch c nng F1 n F12 Cc phm Ctrl, Alt, Shift

Tham s ty chn quy nh cc phm t hp c kt hp vi phm t, bao gm NOINVERT, ALT, SHIFT, CONTROL. Gi tr NOINVERT quy nh chc nng s khng c kch hot khi bm phm tt tng ng, cn ALT, SHIFT, CONTROL l cc phm s c kt hp lm phm tt. V d mt bng phm nh sau:
IDR_MYMENU ACCELERATORS DISCARDABLE BEGIN "1", ID_CAPNHAT_NHAPMOI, VIRTKEY, CONTROL, NOINVERT "2", ID_CAPNHAT_SUACHUA, VIRTKEY, CONTROL, NOINVERT "A", ID_TIMKIEM_TIMTHEOQUEQUAN, VIRTKEY, ALT, NOINVERT "B", ID_TIMKIEM_TIMTHEOTEN, VIRTKEY, ALT, NOINVERT VK_F1, ID_BAOCAO_BAOCAODOANHTHU, VIRTKEY, CONTROL, NOINVERT VK_F2, ID_BAOCAO_BAOCAOLOINHUAN, VIRTKEY, CONTROL, NOINVERT VK_F3, ID_BAOCAO_BAOCAOTONKHO, VIRTKEY, CONTROL, NOINVERT END

Ch : Bng cc phm tt c nh ngha trong tp ti nguyn *.rc ca chng trnh cng vi thc n. Bc 2: Sau khi to bng cc phm tt cho cc chc nng trn thc n chng ta phi np bng phm ny vo chng trnh mi s dng c, bng cch dng hm LoadAccelTable() ca lp CFrameWnd nh sau:
BOOL LoadAccelTable( LPCTSTR lpszResourceName );

Trong tham s lpszResourceName l tn ca bng phm tt nh ngha, nu l s nguyn phi chuyn v dng LPSTR bng p kiu. Thc hin np bng phm vo chng trnh sau khi to ca s bng lnh Create(), thng vit trong hm to ca lp ca s tng ng.

65

V d 3.4
Lp trnh to ca s c thc n v hin thng bo khi chn thc n , ng thi t cc phm nng cho cc chc nng tng ng trn thc n.
/* T p nh ngha cc tn h ng resource.h */ #define IDR_MYMENU 101 #define ID_CAPNHAT_NHAPMOI 40001 #define ID_CAPNHAT_SUACHUA 40002 #define ID_CAPNHAT_XEMDANHSACH 40003 #define ID_HETHONG_TROGIUP 40007 #define ID_HETHONG_THOAT 40008 /* T p cc ti nguyn g m th c n v b ng phm main.rc */ IDR_MYMENU MENU DISCARDABLE BEGIN POPUP "Cap nhat du lieu" BEGIN MENUITEM "Nhap moi\t Ctrl+1", ID_CAPNHAT_NHAPMOI MENUITEM "Sua chua\tAlt+2", ID_CAPNHAT_SUACHUA MENUITEM "Xem danh sach\tCtrl+A", ID_CAPNHAT_XEMDANHSACH END POPUP "He thong chuong trinh" BEGIN MENUITEM "Tro giup\tF1", ID_HETHONG_TROGIUP MENUITEM "Thoat\tCtrl+Atl+F4", ID_HETHONG_THOAT END END // Accelerator IDR_MYMENU ACCELERATORS DISCARDABLE BEGIN "1", ID_CAPNHAT_NHAPMOI, VIRTKEY, CONTROL, NOINVERT "2", ID_CAPNHAT_SUACHUA, ASCII, ALT, NOINVERT VK_F1, ID_HETHONG_TROGIUP, VIRTKEY, NOINVERT VK_F4, ID_HETHONG_THOAT, VIRTKEY, CONTROL, ALT, NOINVERT "^A", ID_CAPNHAT_XEMDANHSACH, ASCII, NOINVERT END /* T p n i dung chng trnh chnh main.cpp */ #include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance();

66

}; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnNhapmoi(); afx_msg void OnSuachua(); afx_msg void OnXemdanhsach(); afx_msg void OnTrogiup(); afx_msg void OnThoat(); DECLARE_MESSAGE_MAP() }; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND( ID_CAPNHAT_NHAPMOI , OnNhapmoi ) ON_COMMAND( ID_CAPNHAT_SUACHUA , OnSuachua ) ON_COMMAND( ID_CAPNHAT_XEMDANHSACH , OnXemdanhsach ) ON_COMMAND( ID_HETHONG_TROGIUP , OnTrogiup ) ON_COMMAND( ID_HETHONG_THOAT , OnThoat ) END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL,"Chuong trinh vi du 04 - Chapter 03"); //Load & set menu for program CMenu *m = new CMenu; m->LoadMenu(IDR_MYMENU); SetMenu(m); //Load table of accelerator LoadAccelTable((LPSTR)IDR_MYMENU); } afx_msg void CMyWin::OnNhapmoi() { MessageBox("Ban da chon muc nhap moi","Thong bao",MB_OK+ MB_ICONEXCLAMATION);

67

} afx_msg void CMyWin::OnSuachua() { MessageBox("Ban da chon muc sua chua","Thong bao",MB_OK | MB_ICONQUESTION); } afx_msg void CMyWin::OnXemdanhsach() { MessageBox("Ban da chon muc xem danh sach","Thong bao",MB_OK | MB_ICONINFORMATION); } afx_msg void CMyWin::OnTrogiup() { MessageBox("Ban da chon muc tro giup","Thong bao",MB_OK | MB_ICONHAND); } afx_msg void CMyWin::OnThoat() { //Dong cua so & thoat khoi chuong trinh MessageBox("Ban da chon muc thoat","Thong bao",MB_OK | MB_ICONSTOP); OnClose(); } CMyApp theApp;

Kt qu khi chy chng trnh v bm phm ^A (Ctrl+A) s xut hin nh sau:

68

3.2.4. Lp CMenu cho thc n


Trong th vin ca MFC cung cp lp CMenu to v qun l thc n ca chng trnh, mi thc n s c qun l bi mt i tng CMenu. Trong lp ny c cc hm thnh vin thc hin thao tc trn thc n nh sau: - Hm to thc n ngang
BOOL CreateMenu()

Hm ny s tr v gi tr TRUE nu to thnh cng v ngc li s tr v gi tr FALSE. - Hm to thc n dc (popup menu)


BOOL CreatePopupMenu( );

Lnh to ny cho php to cc thc n ng cnh (context menu) khi bm chut phi vo mt v tr no trn ca s. - Hm thm mc chn vo thc n
BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

hoc
BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

Trong : + nFlags: l gi tr c xc nh mc chn s thm vo gm cc gi tr sau:


Gi tr c MF_STRING MF_SEPARATOR MF_POPUP MF_MENUBREAK ngha M c ch n l m t chu i k t M c ch n l d u ngn cch M c ch n c th c n d c T o m c ch n trn danh sch m i

+ nIDNewItem: l s hiu mc chn s thm vo thc n, s hiu ny c s dng nh danh v x l la chn ca ngi dng trong chng trnh.
69

Ch : Nu gi tr c l MF_POPUP th tham s ny s l s hiu (HMENU) ca thc n con cho mc chn , gi tr s hiu ca mt thc n ny c lu trong thnh phn m_hMenu ca i tng lp CMenu. + lpszNewItem: l dng ch hin trn mc chn ca thc n. + *pBmp: l nh bitmap c gn vi mc chn, i tng nh bitmap s c trnh by phn sau. - Chn mc chn vo thc n
BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

hoc:
BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

Cc tham s ging nh lnh thm mc chn AppendMenu() trn, c thm tham s nPosition xc nh v tr ca mc chn cn thm trong danh sch ca thc n. Gi tr nPosition c th xc nh v tr hoc s hiu chc nng tng ng vi gi tr c nFlags c cha MF_BYPOSITION hoc MF_BYCOMMAND. - Xa b mc chn trn thc n
BOOL RemoveMenu( UINT nPosition, UINT nFlags );

Trong UINT nPosition l v tr hoc s hiu ca mc chn cn xa, ty thuc vo gi tr nFlags l MF_BYCOMMAND hoc MF_BYPOSITION. - Ly thc n chn dc (thc n con)
CMenu* GetSubMenu( int nPos ) const;

Hm tr v bin tr kiu CMenu ca thc n con dc ca mt thc n ngang ti mt v tr nPos c a vo. - Hm nh du mc chn trn thc n
UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck );

Hm tr v gi tr trng thi mc chn trc khi nh du, c th l MF_CHECKED, MF_UNCHECKED hoc gi tr 0xFFFFFFFF nu nh mc chn khng tn ti.
70

Trong nIDCheckItem l s hiu hoc v tr ca mc chn cn nh du, ty thuc vo tham s nCheck c kt hp t cc gi tr MF_BYCOMMAND, MF_BYPOSITION v MF_CHECKED, MF_UNCHECKED. - Hm thay i trng thi ca mc chn thc n
UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );

Hm tr v trng thi trc (MF_DISABLED, MF_ENABLED, MF_GRAYED, hoc -1). Trong gi tr nIDEnableItem l s hiu hoc v tr ca mc chn cn thao tc, nEnable l gi tr trng thi c kt hp t 1 trong 2 gi tr MF_BYCOMMAND, MF_BYPOSITION vi 1 trong 3 gi tr MF_DISABLED, MF_ENABLED v MF_GRAYED. - Hm hin thc n dng popup (thc n ng cnh)
BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL );

Trong : + int x,y: l ta xc nh v tr cn hin thc n trn ca s. Ta ny phi tnh theo mn hnh, t gc tri trn ca mn hnh. + UINT nFLags: gi tr c hin thc n, bao gm:
Gi tr c TPM_CENTERALIGN TPM_LEFTALIGN TPM_RIGHTALIGN TPM_LEFTBUTTON TPM_RIGHTBUTTON ngha T a x s cn gi a th c n T a x s cn tri th c n T a x s cn ph i th c n Ch n th c n b ng chu t tri Ch n th c n b ng chu t ph i

+ CWnd* pWnd: l tham s xc nh ca s cha thc n ng cnh khi hin th, + LPCRECT lpRect: l tham s xc nh khung gii hn ca s hin thc n, mc nh l NULL.
71

- Hm thay i mc chn trn thc n


BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

hoc:
BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

C th thay i mt chc nng xc nh theo v tr hoc s hiu nu gi tr nFlags l MF_BYPOSITION hoc MF_BYCOMMAND, vi chc nng c xc nh chng ta c th thay s hiu bi mt s hiu mi nIDNewItem hoc thay i ni dung ca chc nng bi lpszNewItem hoc dng nh pBmp. - Hm t hnh nh cho chc nng ca thc n
BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked );

Xc nh chc nng cn t hnh nh bng tham s nPosition v nFLags nh cc hm khc, ngoi ra tham s pBmpUnchecked xc nh hnh nh trng thi khng chn, pBmpChecked xc nh hnh nh ca chc nng trng thi chn. Hnh cn t phi di dng bitmap thng qua i tng lp CBitmap, s c trnh by phn sau. - Hm xa b ti nguyn thc n khi i tng CMenu
BOOL DestroyMenu( );

Ch : Ngoi ra nu cn lm vic thc n h thng ca ca s chng ta cng s dng lp CMenu bng cch xc nh con tr n n bng lnh sau:
CMenu* GetSystemMenu( BOOL bRevert ) const;

Trong tham s bRevert quy nh thc n c c khi phc li trng thi ban u hay khng, nu bng TRUE c khi phc v FALSE nu ngc li.
72

Hm tr v con tr kiu lp CMenu ti i tng thc n ca ca s, thng thng thc n ny c cc chc nng sau:

Tuy nhin chng ta c th thay i nu cn thit v nh x thng ip chn cc chc nng ti cc hm thnh vin mong mun ca lp ca s tng ng.

V d 3.5
Lp trnh to ca s vi thc n ngang c to v qun l bng mt i tng CMenu gm cc chc nng: File, Edit, Tools, Help. X l thng ip nt phi chut to v hin ln ca s thc n ng cnh vi cc chc nng nh: Phng to, Thu nh, ng. Thc hin x l cc thng ip chn chc nng ca thc n ng cnh tng ng.
/* T p tin nh ngha cc tn h ng m c ch n - resource.h */ #define IDM_FILE 10004 #define IDM_EDIT 10005 #define IDM_TOOL 10006 #define IDM_HELP 10007 #define IDM_CONTEXT_MAX 100011 #define IDM_CONTEXT_MIN 100012 #define IDM_CONTEXT_RES 100013 /* T p tin chng trnh chnh - main.cpp */ #include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd {

73

public: CMyWin(); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnMax(); afx_msg void OnMin(); afx_msg void OnRes(); DECLARE_MESSAGE_MAP() }; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_RBUTTONDOWN() ON_COMMAND( IDM_CONTEXT_MAX, OnMax ) ON_COMMAND( IDM_CONTEXT_MIN, OnMin ) ON_COMMAND( IDM_CONTEXT_RES, OnRes ) END_MESSAGE_MAP() CMyWin::CMyWin() { Create(NULL,"Chuong trinh vi du 05 - Chapter 03"); //Create & set menu for program CMenu *m = new CMenu; m->CreateMenu(); m->AppendMenu(MF_BYCOMMAND,IDM_FILE,"File"); m->AppendMenu(MF_BYCOMMAND,IDM_EDIT,"Edit"); m->AppendMenu(MF_BYCOMMAND,IDM_TOOL,"Tools"); m->AppendMenu(MF_BYCOMMAND,IDM_HELP,"Help"); SetMenu(m); } afx_msg void CMyWin::OnRButtonDown(UINT nFlags, CPoint point) { CRect r1; int h1 = GetSystemMetrics(SM_CYCAPTION); h1 = h1 + GetSystemMetrics(SM_CYMENU); CMenu *m = new CMenu; m->CreatePopupMenu(); m->AppendMenu(MF_BYCOMMAND,IDM_CONTEXT_MAX,"Phong to");

74

m->AppendMenu(MF_BYCOMMAND,IDM_CONTEXT_MIN,"Thu to"); m->AppendMenu(MF_BYCOMMAND,IDM_CONTEXT_RES,"Binh thuong"); GetWindowRect(&r1); m->TrackPopupMenu(TPM_LEFTALIGN,r1.left+point.x,r1.top+point.y+h1,this); } afx_msg void CMyWin::OnMax() { ShowWindow(SW_SHOWMAXIMIZED); } afx_msg void CMyWin::OnMin() { ShowWindow(SW_SHOWMINIMIZED); } afx_msg void CMyWin::OnRes() { ShowWindow(SW_RESTORE); } CMyApp theApp;

Trong chng trnh c s dng lnh xc nh kch thc tiu ca s v thc n ngang, l:
int GetSystemMetrics( int nIndex );

Lnh ny s tr v gi tr ca cc tham s h thng xc nh trong tham s nIndex, bao gm mt s tham s sau:


Gi tr nIndex SM_CMOUSEBUTTONS SM_CXBORDER, ...CY... SM_CXCURSOR, ...CY... SM_CXFULLSCREEN, ...CY... SM_CXICON, ...CY... SM_CXSCREEN, ...CY... SM_CYCAPTION SM_CYMENU SM_MOUSEPRESENT SM_MOUSEWHEELPRESENT ngha (tr l i) S nt chu t dy c a ng vi n theo x, y l n c a con tr chu t theo x,y l n c a c a s khi phng to x,y l n c a bi u t ng theo x,y l n c a mn hnh theo x,y cao c a tiu c a s cao c a th c n c a s C chu t hay khng Chu t c nt cu n hay khng

75

V lnh hin thc n ng cnh TrackPopupMenu() i hi phi xc nh ta mn hnh nn chng ta phi ly ta ca chut trn ca s cng vi ta ca s v thm cao ca tiu vi thc n. Kt qu ca chng trnh s nh sau:

Ch : C th ly thc n h thng trn ca s (nm gc tri trn) v thay i n qua lp CMenu. C php thc hin bng lnh sau:
CMenu* GetSystemMenu( BOOL bRevert ) const;

Hm tr v con tr ti i tng thc n ng vi ca s, tham s bRevert quy nh thc n sau khi ly v thay i c c khi phc li hay khng ng vi TRUE hoc FALSE. C th thm hoc bt cc mc chn trong thc n h thng ca ca s, vi cc mc chn mi c th nh x x l bi cc hm trong lp ca s tng ng. V d sau minh ha thc n h thng ca ca s b thay i:

76

3.3. Biu tng v nh (icon, cursor, bitmap)


Biu tng chng trnh v chut l nhng thnh phn quan trng ca cc ng dng trn Windows, tuy nhin trong cc chng trnh trc y u s dng biu tng mc nh ca Windows. Trong phn ny s trnh by cch to v s dng nhng biu tng theo mong mun. Biu tng v hnh nh l nhng ti nguyn ca chng trnh, c to ra bng nhng chng trnh bin tp hnh nh. Sau khi to thnh cng cc biu tng hnh nh s c nh ngha vo trong tp ti nguyn ca chng trnh. Trc khi s dng chng ta phi np vo my tnh t chng trnh. Ni dung ba loi ti nguyn ny c lu trong ba loi tp tin sau: + ICON lu trong tp c phn m rng l: *.ico, + CURSOR lu trong tp c phn m rng l: *.cur, + BITMAP lu trong tp c phn m rng l: *.bmp. nh ngha mt ti nguyn biu tng, nh trong chng trnh chng ta s dng theo cch sau:
tn_icon tn_sursor tn_bitmap ICON CURSOR BITMAP tn_tp_lu_icon tn_tp_lu_cursor tn_tp_lu_bitmap

V d chng ta c 3 biu tng nh lu trong 3 tp nh sau:


mybitmap.bmp mycursor.cur myicon.ico

Lnh nh ngha cc biu tng nh vo trong tp ti nguyn chng trnh l:


MYBITMAP BITMAP mybitmap.bmp MYCURSOR CURSOR mycursor.cur MYICO ICO myico.ico

77

Ch : Cc tp lu nh biu tng ny phi c chp vo cng vi th mc ca chng trnh, trong th mc project ca chng trnh. Mi ti nguyn biu tng hnh nh khi np vo my trong chng trnh s c qun l bng mt s hiu gm: HICON, HCURSOR, HBITMAP.

3.3.1. Np v s dng ICON v CURSOR


np cc ti nguyn biu tng hnh nh ny vo my khi chy chng trnh chng ta s dng cc hm thnh vin ca lp ng dng CWinApp nh sau: - Np ti nguyn biu tng ICON
HICON CWinApp :: LoadIcon( tn_s_hiu_ti_nguyn );

- Np ti nguyn biu tng CURSOR


HCURSOR CWinApp :: LoadCursor( tn_s_hiu_ti_nguyn );

Ngoi ra c th s dng cc ti nguyn biu tng sn c trong Windows v np bng cc lnh sau:
HICON CWinApp :: LoadStandardIcon( tn_ti_nguyn ); CWinApp :: LoadStandardCursor( tn_ti_nguyn ); HCURSOR

Vi gi tr tn ti nguyn ca icon s l mt trong cc gi tr sau:


Tn ti nguyn IDI_ASTERISK IDI_EXCLAMATION IDI_HAND IDI_QUESTION IDI_WINLOGO ngha Thng tin C nh bo D ng H i Lg c a windows

Gi tr tn ti nguyn ca cursor cung cp bi Windows c th l:


Tn ti nguyn IDC_ARROW IDC_CROSS IDC_IBEAM IDC_WAIT ngha Mi tn Ch th p Ch I (con tr nh p li u) ng h ct

78

Ti nguyn biu tng ICON s c s dng gn cho ca s ca chng trnh v c th thc hin bng lnh SetIcon() bt k thi im no sau khi to xong ca s trong chng trnh:
HICON CWnd :: SetIcon( HICON hIcon, BOOL bBigIcon );

L mt hm thnh vin ca lp CWnd, trong tham s hIcon xc nh s hiu icon c np, bBigIcon cho bit icon trng thi nh hay to. Hm s tr v s hiu icon c ca s trc khi t mi. i vi vic t biu tng cursor chng ta phi s dng lp ca s (window class), lp ca s l cu trc cha cc gi tr ca cc tham s lin quan n vic thit lp mt ca s. Lp ca s phi c ng k ri mi to ca s, tuy nhin trong cc v d trc chng ta s dng lp ca s mc nh ca MFC cung cp. Phn ny chng ta s dng lnh sau ng k lp ca s v thit lp cc tham s bao gm: kiu lp ca s, biu tng cursor, kiu nn ca s, biu tng icon.
LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0 );

Trong nClassStyle xc nh kiu lp ca s, hCursor v hIcon xc nh hai biu tng con tr chut v biu tng ca s, hbrBackground xc nh kiu nn ca s. Thng thng tham s nClassStyle t bng NULL v my s ly mc nh, cn tham s hCursor v hIcon l s hiu biu tng cn t, c th s dng kt qu ca lnh np hai biu tng nh sau:
HCURSOR :: LoadCursor()

v
UICON :: LoadIcon().

Hm ng k lp ca s s tr v gi tr tn ca mt lp ca s ng k thnh cng, gi tr ta a vo tham s u tin ca lnh to Create() trong lp ca s.


Create( tn_lp_ca_s , tiu__ca_s )

79

Ngoi ra, tham s hbrBackground s ly mc nh l mu trng hoc s dng lnh sau xc nh cc kiu nn c sn ca Windows:
HGDIOBJ GetStockObject( int fnObject );

Trong tham s fnObject c th mt trong cc gi tr sau chn kiu nn: WHITE_BRUSH (nn trng), LTGRAY_BRUSH (nn xm nht), BLACK_BRUSH (nn en), GRAY_BRUSH (nn xm), DKGRAY_BRUSH (nn xm m). Hm ny tr v mt gi tr kiu HGDIOBJ v chng ta s p thnh kiu HBRUSH t vo tham s trong lnh ng k trn.

V d 3.6
Lp trnh to mt ca s v t biu tng ca s cng nh biu tng chng trnh theo hnh nh to hoc ly mc nh.
/* T p nh ngha cc tn h ng - resource.h */ #define IDI_MYICON 102 #define IDC_MYCURSOR 103 /* T p nh ngha cc ti nguyn - main.rc */ #include "resource.h" IDI_MYICON ICON DISCARDABLE IDC_MYCURSOR CURSOR DISCARDABLE /* T p chng trnh chnh - main.cpp */ #include<afxwin.h> #include"resource.h" /* Khai bo l p ng d ng v l p c a s chng trnh */ class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); }; /* T o i t ng ng d ng */

"icon2.ico" "cursor1.cur"

80

CMyApp theApp; /* Vi t l nh cho hm kh i t o ng d ng */ BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } /* Vi t l nh cho hm t o c a l p c a s */ CMyWin::CMyWin() { /* L y bi u t ng chng trnh trong ti nguyn */ HICON a = theApp.LoadIcon(IDI_MYICON); /* L y bi u t ng chu t trong ti nguyn */ HCURSOR b = theApp.LoadCursor(IDC_MYCURSOR); /* L y ki u n n c a s c s n trong h th ng */ HBRUSH c = (HBRUSH)GetStockObject(GRAY_BRUSH); /* ng k l p c a s vo h th ng */ LPCSTR d = AfxRegisterWndClass(NULL,b,c,a); /* T o c a s m i theo l p ng k */ Create(d , "Chuong trinh vi du 06 - Chapter 03"); }

Trong hm to ca lp ca s chng ta s dng i tng ng dng (theApp) cng cc hm tng ng np cc biu tng v ng k lp ca s, tip theo to ca s nh thng thng. V trong hm to ca lp ca s c s dng i tng theApp nn n phi c to ra trc , nh trong v d trn, ngay sau khai bo lp. Chng trnh khi chy th s nh sau:

81

3.3.2. Np v s dng nh bitmap


Ti nguyn nh bitmap c s dng to cc giao din ca chng trnh, nh t cho cc nt lnh, chc nng ca thc n, hoc c th hin ln ca s. np v s dng ti nguyn nh bitmap trong chng trnh chng ta s dng i tng ca lp CBitmap thc hin vi cc bc sau: Bc 1: Np nh bitmap vo my
BOOL CBitmap :: LoadBitmap( tn_s_hiu_nh );

Bc 2: To vng nh s lu gi nh bitmap cho vic hin th tng ng vi ca s cn hin th nh, s dng i tng ca lp CDC
BOOL CDC :: CreateCompatibleDC( CDC* pDC );

Trong pDC l a ch ca ng cnh ca s cn hin th nh s ly c qua hm GetDC(). Bc 3: t nh bitmap np vo vng nh to c bc 2


CBitmap* CDC :: SelectObject( CBitmap* pBitmap );

Trong pBitmap l a ch ca i tng CBitmap to ra v np nh bc 1. Hm ny tr v nh c t trc trong vng nh. Bc 4: Chp ni dung hnh nh t i tng bitmap vo ng cnh ca s hin th
BOOL CDC :: BitBlt ( int x, int y, int nWidth, int nHeight, CDC* SrcDC, int xSrc, int ySrc, DWORD dwRop );

Trong x,y l ta xc nh v tr trn ca s cn chp nh n, nWidth v nHeight xc nh rng, chiu cao ca nh cn chp. SrcDC l a ch ca ng cnh b nh to v t lu nh bc 2 v bc 3. xSrc v ySrc xc nh ta gc tri trn ca nh s chp ln ca s v dwRop l ch chp, bao gm: SRCAND, SRCCOPY, SRCINVERT, SRCPAINT. Thng thng s dng ch chp (SRCCOPY).
82

V d 3.7
Lp trnh to ca s v t mt s nh bitmap ln cc chc nng ca thc n. X l bm nt tri chut hin nh bitmap ln ca s ti v tr nhn chut. Chng ta phi khai bo cc i tng kiu CBitmap trong lp ca s lu cc nh bitmap khi t ln chc nng ca thc n.
/* T p ch a nh ngha cc tn h ng - resource.h */ #define IDB_BITMAP1 101 #define IDB_BITMAP2 102 #define IDB_BITMAP3 103 #define IDB_BITMAP4 104 #define IDM_ITEM1 1011 #define IDM_ITEM2 1022 #define IDM_ITEM3 1033 /* T p nh ngha cc ti nguyn nh bitmap - main.rc */ #include "resource.h" IDB_BITMAP1 BITMAP DISCARDABLE "bitmap1.bmp" IDB_BITMAP2 BITMAP DISCARDABLE "bitmap2.bmp" IDB_BITMAP3 BITMAP DISCARDABLE "bitmap3.bmp" IDB_BITMAP4 BITMAP DISCARDABLE "bitmap4.bmp" /* T p chng trnh chnh - main.cpp */ #include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CBitmap bmp[3]; CMenu m; public: CMyWin(); afx_msg void OnLButtonDown(UINT nFLags, CPoint point); DECLARE_MESSAGE_MAP() };

83

CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { HICON a = theApp.LoadStandardIcon(IDI_QUESTION); HCURSOR b = theApp.LoadStandardCursor(IDC_CROSS); HBRUSH c = (HBRUSH)GetStockObject(WHITE_BRUSH); LPCSTR d = AfxRegisterWndClass(NULL,b,c,a); Create( d , "Chuong trinh vi du 07 - Chapter 03" ); //Create & set menu to the window m.CreateMenu(); bmp[0].LoadBitmap(IDB_BITMAP1); m.AppendMenu(MF_BYCOMMAND, IDM_ITEM1, &bmp[0]); bmp[1].LoadBitmap(IDB_BITMAP2); m.AppendMenu(MF_BYCOMMAND, IDM_ITEM2, &bmp[1]); bmp[2].LoadBitmap(IDB_BITMAP3); m.AppendMenu(MF_BYCOMMAND, IDM_ITEM3, &bmp[2]); SetMenu(&m); } afx_msg void CMyWin::OnLButtonDown(UINT nFLags, CPoint point) { CBitmap a; a.LoadBitmap(IDB_BITMAP4); CDC d,*c=GetDC(); d.CreateCompatibleDC(c); d.SelectObject(&a); c->BitBlt(point.x, point.y, 160, 120, &d, 0, 0, SRCCOPY); }

84

Kt qu chng trnh sau khi bm chut tri vo cc im trn ca s s c nh sau:

3.4. Hp hi thoi (dialog box) v lp CDialog


3.4.1. C bn v hp thoi
Hp thoi (dialog) l mt kiu ca s to nn tng tc gia ngi dng v chng trnh mt cch mm do. Nhn chung cc hp thoi cho php ngi dng la chn hoc in cc thng tin m khng th hoc rt kh thc hin bng thc n (menu). Hp thoi c mt hu ht trong mi ng dng, l mt phn rt ln trong lp trnh cc ng dng. Vi khun kh ti liu ny chng ti ch cp n cc hp thoi dng n gin. Trn hp thoi c cc iu khin (controls) ngi dng tng tc, mt iu khin cng l mt kiu ca s c bit nhp hoc hin d liu. Cc iu khin u c cha trong mt ca s m, l hp thoi. Mt s iu khin n gin nh sau: nt bm (push button), hp kim tra (check box), nt chn (radio button), nhp liu (text box),...
85

Mt v d v hp thoi chn phng ch ca ng dng Word:

Trn Windows c hai loi hp thoi: loi modal c c trng l phi c kt thc trc khi tip tc trn ca s m, hu ht chng ta dng loi ny; loi modeless khng cn phi kt thc, tc l c th tip cng vic trn ca s m m khng cn ng n. Sau y l mt s vn c bn v hp thoi: i) Cch nh ngha ti nguyn hp thoi Hp thoi tn ti di dng ti nguyn ca chng trnh, c nh ngha bn trong tp ti nguyn (*.rc) ca chng trnh. Mu khai bo mt hp thoi nh sau:
86

tn-hp-thoi CAPTION STYLE {

DIALOG

[ty-chn]

X, Y, Width, Height

tiu--hp-thoi kiu-hp-thoi

nh-ngha-cc-iu-khin-trn-hp-thoi }

Trong kiu hp thoi (STYLE) gm cc gi tr sau:


Gi tr ki u DS_MODALFRAME WS_BORDER WS_CAPTION WS_CHILD WS_HSCROLL WS_MAXIMIZEBOX WS_MINIMIZEBOX WS_SYSMENU WS_TABSTOP WS_VISIBLE WS_VSCROLL ngha H p tho i c khung ki u modal C vi n C tiu L c a s con C thanh cu n ngang C nt ch n phng to C nt ch n thu nh C th c n h th ng C th dng Tab trn h p tho i H p tho i s th y ngay khi hi n C thanh cu n d c

Khai bo ny t trong tp ti nguyn *.RC ca chng trnh (cng vi thc n,...). nh ngha cc iu khin s trnh by phn tip sau. ii) Lp CDialog lm vic vi hp thoi Trong chng trnh s dng v qun l hp thoi chng ta s dng lp CDialog ca th vin MFC, c dn xut t lp CWnd. Lp CDialog c 3 mu hm to nh sau:
CDialog ( LPCSTR lpszDName, CWnd *Owner = NULL); //mu1 CDialog ( UINT CDialog ( ); ID, CWnd *Owner = NULL); // mu 2 // mu 3

87

Trong mu 1 v 2 dng to i tng, ng thi gn vi hp thoi c tn lpszDName hoc s hiu ID nh ngha ti nguyn, tham s Owner l con tr kiu CWnd xc nh ca s m cha hp thoi. Mu 3 dng to hp thoi dng Modeless s trnh by sau. iii) X l thng ip cho hp thoi K thut x l thng ip trn hp thoi tng t vi ca s, mi iu khin trn hp thoi c mt s hiu (ID) nn khi chng ta - ngi dng tc ng s pht sinh thng ip WM_COMMAND gi ti chng trnh, v vy chng ta s dng macro ON_COMMAND nh x vic x k thng ip. i km vi thng ip WM_COMMAND c cc tham s nh s hiu ca iu khin tc ng, kiu tc ng ca ngi dng,... Chng ta nn nh ngha mt lp mi dn xut t lp CDialog thc hin vic nh x v x l cc thng ip cn thit cho hp thoi c to ra. iv) Hin v ng hp thoi i vi hp thoi kiu Modal chng ta s dng hm thnh vin sau ca lp CDialog hin hp thoi:
virtual int CDialog :: DoModal();

Hm tr v gi tr m kt thc ca hp thoi khi ng, hoc tr v -1 nu hin khng thnh cng, hoc tr v IDABORT nu b li sau khi hin. Trong trng hp bnh thng th ch khi ng hp thoi lnh DoModal() trn mi tr v gi tr. ng hp thoi khi cn chng ta dng hm thng ip sau (ng vi hai nt lnh Ok v Cancel) c xy dng sn trong lp CDialog:
void CDialog :: OnOk();

hoc
void CDialog :: OnCancel();

Khi chn nt Close ( gc phi trn hp thoi) th my s t ng thc hin hm OnCancel().

88

3.4.2. nh ngha cc iu khin trn hp thoi


i) iu khin Static text dng hin vn bn tnh ln hp thoi c khai bo nh sau:
CTEXT " xu-k-t " , s-hiu , X, Y, Width, Height , kiu

thay t kha CTEXT bng LTEXT hoc RTEXT c cc text cn chnh gia, tri, phi. ii) iu khin Push button l cc nt lnh chn trn hp thoi, c khai bo nh sau:
PUSHBUTTON kiu " xu-hin-th " , s-hiu , X , Y , Width , Height ,

hoc thay bng t kha DEFPUSHBUTTON u t mc nh. iii) iu khin Editbox nhp d liu trn hp thoi, khai bo l:
EDITTEXT s-hiu , X , Y , Width , Height , kiu

iv) iu khin List/Combobox dng hin th danh sch chn, khai bo l:


LISTBOX s-hiu , X , Y , Width , Height , kiu

hoc thay LISTBOX bng COMBOBOX. v) iu khin Checkbox to cc hp nh du kim tra, khai bo:
CHECKBOX "xu", s-hiu, X, Y, Width, Height, kiu

vi) iu khin GROUPBOX nhm cc iu khin khc thnh nhm


GROUPBOX "xu" , s-hiu , X, Y, Width, Height, kiu

vii) iu khin RADIOBUTTON to cc nt chn


AUTORADIOBUTTON "xu", s-hiu, X, Y, Width, Height, kiu

hoc dng khai bo sau:


CONTROL "xu", s-hiu, X, Y, Width, Height, kiu

vi tham s kiu l BS_AUTORADIOBUTTON. viii) iu khin SCROLLBAR to cc thanh cun


SCROLLBAR s-hiu, X, Y, Width, Height, kiu

89

Trong cc tham s trn c: "xu" l tiu hin th trn iu khin, X v Y l ta ca iu khin trn hp thoi, Width & Height l rng v chiu cao ca iu khin, kiu xc nh cc tham s khc cho iu khin v c th c hoc khng. Mi iu khin phi c mt s hiu khi x l trong lp trnh u thng qua s hiu ny mi tc ng ln cc iu khin. Tham s kiu bao gm cc gi tr ca kiu ca s nh trn v mt s gi tr khc sau:
Gi tr LBS_NOTIFY SBS_VERT SBS_HORZ CBS_DROPDOWN CBS_SORT ES_MULTILINE ngha Cho php x l cc thng i p Ki u thanh cu n d c Ki u thanh cu n ngang Ki u danh sch th C s p cc m c ch n Editbox c nhi u dng

Tuy nhin d dng trong vic to hp thoi v cc iu khin chng ta s dng cng c ca Visual C s c trnh by phn cui chng.

V d 3.8
Lp trnh to mt ca s c thc n hin hp thoi theo mu sau:

Chng ta nh ngha hp thoi vi cc iu khin trong tp ti nguyn nh sau:


90

IDR_MENU1 MENU DISCARDABLE BEGIN MENUITEM "Dialog", IDM_DIALOG END IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 237, 148 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Hop thoai don gian" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,58,120,50,14 PUSHBUTTON "Cancel",IDCANCEL,125,120,50,14 CTEXT "THONG TIN CA NHAN",IDC_STATIC,67,20,103,12 LTEXT "Ho va ten",IDC_STATIC,25,47,36,12 EDITTEXT IDC_EDIT1,65,47,145,14,ES_AUTOHSCROLL LTEXT "Ngay sinh",IDC_STATIC,25,63,36,12 EDITTEXT IDC_EDIT2,65,63,145,14,ES_AUTOHSCROLL LTEXT "Gioi tinh",IDC_STATIC,25,80,36,12 CONTROL "Nam",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,101,80,33, 13 CONTROL "Nu",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,65,80,33,13 LTEXT "Que quan",IDC_STATIC,25,96,36,12 COMBOBOX IDC_COMBO1,65,96,80,15,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP END

Lp chng trnh nh sau:


#include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); void OnDialog(); DECLARE_MESSAGE_MAP() };

91

CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND( IDM_DIALOG , OnDialog ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { CMenu m; Create(NULL,"Chuong trinh vi du 08 - Chapter 03"); m.LoadMenu(IDR_MENU1); SetMenu(&m); } void CMyWin::OnDialog() { CDialog d(IDD_DIALOG1 , this); int kq=d.DoModal(); if (kq==IDOK) { MessageBox("Ban da chon nut Ok"); } else { MessageBox("Ban da chon nut Cancel"); } }

Trong hm OnDialog x l thng ip chn thc n IDM_DIALOG ca lp CMyWin, chng ta khai bo i tng kiu CDialog v s dng hp thoi vi s hiu IDD_DIALOG1, sau gi hm DoModal() s hin hp thoi v lm vic. Khi kt thc my tr v IDOK hoc IDCANCEL ph thuc chn nt lnh trn hp thoi. Kt qu giao din chng trnh khi chy l:
92

3.5. X l cc iu khin trn hp thoi


Mun tc ng ln cc iu khin trn hp thoi chng ta phi nh ngha lp dn xut t CDialog v nh x thng ip ti cc hm tng ng. Sau y l mt s hm thc hin trn cc iu khin ca hp thoi. Mi iu khin c th c qun l bi mt i tng thuc lp tng ng, trong chng trnh c th to cc lp dn xut lm vic cho tng loi iu khin hoc s dng lp sn c, bao gm:
Tn l p CEdit CButton CListBox CComboBox CScrollBar CStatic C a i u khi n Cho editbox Cho nt l nh, h p ki m tra, nt l a ch n Cho listbox Cho combobox Cho thanh cu n Cho hi n vn b n

Mi iu khin s hot ng nh mt ca s, cc lp trn u dn xut t lp CWnd. xc nh iu khin cn thao tc trn hp thoi ta dng hm sau:
CWnd *CWnd :: GetDlgItem ( s-hiu-iu-khin ) const;

93

Hm tr v con tr kiu CWnd nn khi s dng chng ta nn p thnh kiu lp tng ng lm vic cho thun tin. Tuy nhin chng ta c th to v s dng cc iu khin trn ca s bng cch to cc i tng trong ca s tng ng. S dng cc hm to trn tng i tng ca lp iu khin.

3.5.1. Edit box


Editbox l mt iu khin cho php nhp v hin d liu, c hin th bng mt hnh ch nht. iu khin ny c bao gi bi lp CEdit vi cc hm thnh vin sau: Hm to iu khin Editbox:
BOOL CEdit::Create( DWORD st, RECT& rt , CWnd* wp, UINT nID );

Trong : + st quy nh kiu iu khin Editbox thng bao gm WS_VISIBLE, WS_BORDER, WS_CHILD v cc kiu dnh ring cho editbox:
Ki u ES_PASSWORD ES_LEFT/RIGHT/CENTER ES_MULTILINE ES_AUTOVSCROLL/AUTOHSCROLL ES_READONLY ngha T o h p g m t kh u Cn ch nh vn b n g vo Cho php g nhi u dng T ng cu n d li u Ch cho php c, khng s a

+ rt quy nh kch thc v v tr ca iu khin trn hp thoi/ca s. Tham s ny c kiu RECT gm 4 thnh phn {left, top, bottom, right}, + wp quy nh ca s hoc hp thoi cha iu khin to ra, c xc nh bng con tr kiu CWnd, + nID l s hiu ca iu khin phn bit gia cc iu khin vi nhau trong ca s hoc hp thoi. Hm Create() trn s tr v gi tr TRUE nu thnh cng v ngc li tr v FALSE nu tht bi. Cc hm t d liu, ly d liu dng vn bn trn Editbox theo mu sau:
94

int

CWnd :: GetWindowText( LPSTR a-ch-xu, int Max );

void CWnd :: SetWindowText( LPSTR a-ch-xu );

Hm GetWindowText() tr v s k t ly thnh cng. Chng ta s dng hm ny trn iu khin editbox qua lp CEdit. Ngoi ra c mt s hm trong lp CEdit thao tc theo mu sau:
Thng i p EM_GETLIMITTEXT EM_GETLINE EM_GETLINECOUNT EM_GETMODIFY EM_LIMITTEXT EM_LINELENGTH EM_REPLACESEL EM_SETLIMITTEXT EM_SETSEL EM_UNDO Tn hm GetLimitText() GetLine( idx , xu ) GetLineCount() GetModify() LimitText( -di ) LineLength() ReplaceSel( vn-b n-m i, khi-ph c ) SetLimitText( -di ) SetSel(v -tr- u, v -tr-cu i, cu n-khng) Undo() ngha Cho gi i h n text Cho dng vn b n Cho s dng Cho bi t c thay i Gi i h n di nh p Cho di c a d li u Thay th vn b n ch n Gi i h n di ch a Bi en vn b n Khi ph c vn b n

3.5.2. Push button, Checkbox v Radio button


Ba iu khin ny u c bao gi v x l bi lp CButton, cc hm thnh vin trong lp ny c nh ngha theo mu sau: Hm to ra mt iu khin mi trn ca s/hp thoi:
BOOL CButton :: Create( LPCTSTR CWnd* wp, UINT id ); cap, DWORD st, RECT& rt,

Trong : + LPCSTR cap: l xu k t hin trn iu khin nt lnh hoc hp kim tra hoc nt chn, + DWORD st: l tham s quy nh kiu thng gm WS_CHILD, WS_VISIBLE, WS_BORDER v mt s kiu ring cho loi iu khin ny:

95

Gi tr BS_AUTOCHECKBOX BS_AUTORADIOBUTTON BS_AUTO3STATE BS_DEFPUSHBUTTON BS_GROUPBOX BS_LEFTTEXT

ngha T o h p ki m tra v t ng thay i tr ng thi ch n khi b m chu t T o nt ch n v t ng thay i tr ng thi khi b m chu t i u khi n c 3 tr ng thi: ch n, khng ch n, v tr ng thi m T o nt l nh m c nh T o nhm i u khi n Vn b n hi n bn tri i u khi n

+ RECT rt: l kch thc v v tr ca iu khin, + CWnd wp: l ca s m cha iu khin, + UINT id: l s hiu ca iu khin cn to. Hm t trng thi hp kim tra, nt chn (checkbox, radiobutton):
void CButton :: SetCheck( int kiu);

vi gi tr kiu l 1 s bt hp kim tra, ngc li bng 0. hoc hm ly trng thi:


int CButton :: GetCheck();

3.5.3. Combobox v Listbox


iu khin ComboBox thao tc qua i tng lp CComboBox, iu khin listbox thao tc qua lp CListBox. C th thy iu khin ComboBox l kt hp ca hai iu khin editbox v listbox. to hai iu khin ny ln ca s/hp thoi ta s dng lnh sau:
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

Trong cc tham s ca hm Create() tng t nh cc iu khin trc gm kiu (dwStyle), kch thc (rect), ca s m (pParentWnd) v s hiu (nID). Cc kiu ca tham s dwStyle c th dng ngoi WS_CHILD, WS_VISIBLE v WS_BORDER gm:

96

Tn ki u LBS_EXTENDEDSEL LBS_MULTICOLUMN LBS_SORT CBS_AUTOHSCROLL CBS_DROPDOWN CBS_DROPDOWNLIST CBS_SORT

ngha Cho php ch n nhi u m c Hi n th nhi u c t C s p x p cc m c T ng hi n thanh cu n d c Danh sch ch n th xu ng Danh sch ch n d ng list C s p x p

Ngoi ra c hai lp ny c chung mt s hm theo mu sau:


Tn hm int AddString( xu ); int GetCount(); int GetText( idx , xu ); int GetCurSel(); int SetCurSel( idx ); ngha Thm m c ch n Cho s m c ch n Cho m c ch n v tr idx, b t u t 0

Cho v tr m c ang ch n t m c ch n

3.5.4. Scrollbar
iu khin thanh cun (ngang, dc) u c qun l bi lp CScrollBar, do vy chng ta s dng cc hm thnh vin ca lp ny tc ng ln thanh cun. Sau y l mu hm to thanh cun trc tip:
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

Trong tham s dwStyle quy nh kiu i tng thanh cun, 3 tham s cn li nh cc lnh to trn. Gi tr ca tham s kiu c th gm WS_VISIBLE, WS_BORDER, WS_CHILD v:
Tn ki u SBS_BOTTOMALIGN SBS_HORZ SBS_LEFTALIGN SBS_RIGHTALIGN SBS_TOPALIGN SBS_VERT ngha Thanh cu n n m d i cng Thanh cu n ngang Thanh cu n n m pha tri Thanh cu n n m pha ph i Thanh cu n n m pha trn Thanh cu n d c

97

i) X l thng ip thanh cun Khc vi cc iu khin khc my s khng pht sinh thng ip WM_COMMAND gi ti ca s hp thoi, s pht sinh thng ip WM_VSCROLL hoc WM_HSCROLL khi chng ta tc ng ln thanh cun. Khi chng ta phi nh x x l hai thng ip ny vi mu hm khai bo nh sau:
afx_msg void CWnd :: OnVScroll(UINT k, INT v, CScrollBar *s); afx_msg void CWnd :: OnHScroll(UINT k, INT v, CScrollBar *s);

Trong k l kiu tc ng ln thanh cun, v l v tr ca con chy trn thanh cun, s l con tr lp CScrollBar ng vi thanh cun b tc ng. Nu l thanh cun mc nh trn ca s th gi tr s s bng NULL. Kiu tc ng ln thanh cun c th l mt trong cc gi tr sau:
Gi tr ki u SB_LINEUP/LINEDOWN SB_LINELEFT/LINERIGHT SB_PAGEUP/PAGEDOWN SB_PAGELEFT/PAGERIGHT SB_THUMBTRACK SB_THUMBPOSITION SB_TOP SB_BOTTOM ngha D ch con ch y ln ho c xu ng D ch con ch y sang tri ho c ph i D ch con ch y ln/xu ng m t trang D ch tri/ph i m t trang Ko r con ch y trn thanh cu n V tr m i sau khi ko r con ch y Chuy n ln u Chuy n xu ng cu i

ii) Min gii hn v tr ca con chy trn thanh cun Hm t gii hn c mu sau:
void rd); CWnd :: SetScrollRange( int w, int min, int max, BOOL

Trong w l gi tr SB_VERT hoc SB_HORZ ng vi thanh cun dc hoc ngang, min v max l gi tr gii hn di v trn ca con chy, rd l TRUE (mc nh) hoc FALSE xc nh thanh cun c v li sau khi t. Hm trn ch thc hin trn thanh cun ca ca s, thc hin trn iu khin ScrollBar ca hp thoi ta dng hm ca lp CDialog sau:
98

void

CScrollBar :: SetScrollRange(int min, int max, BOOL rd);

Ngc li hm xc nh gii hn ca thanh cun theo mu sau:


void void CWnd :: GetScrollRange( int w, LPINT CScrollBar :: GetScrollRange( LPINT min, LPINT max); min, LPINT max);

Hm tr v hai gi tr min v max qua hai tham s tng ng kiu LPINT (a ch bin kiu int). iii) V tr con chy ca thanh cun Hai hm thc hin t v tr con chy trn thanh cun ca s hoc iu khin trn hp thoi theo mu sau:
int CWnd :: SetScrollPos( int w, int pos, BOOL ReDraw); int CScrollBar :: SetScrollPos( int pos, BOOL ReDraw);

Trong w l gi tr SB_VERT hoc SB_HORZ, pos l v tr mi cn t, ReDraw cho bit c v li hay khng. Hai hm trn tr v gi tr 1 hoc 0 ng vi thnh cng hoc khng. Hm xc nh v tr con chy hin thi l:
int CWnd :: GetScrollPos( int w ); int CScrollBar :: GetScrollPos();

hai hm ny s tr v v tr ca con chy. vi) Ngoi ra chng ta c th t hoc ly thng tin v thanh cun qua cc hm sau:
BOOL CWnd::SetScrollInfo( int w, LPSCROLLINFO if, BOOL rd); BOOL CScrollBar::SetScrollInfo( LPSCROLLINFO if, BOOL rd);

hoc:
BOOL BOOL CWnd::GetScrollInfo( int w, LPSCROLLINFO if, UINT mk); CScrollBar :: GetScrollInfo( LPSCROLLINFO if, UINT mk);

Trong w l gi tr SB_VERT hoc SB_HORZ ca thanh cun trn ca s, if l thng tin v thanh cun xc lp bi cu trc SCROLLINFO v gi tr rd cho bit c v li hay khng.
99

Cu trc SCROLLINFO c nh ngha nh sau:


typedef struct tagSCROLLINFO { UINT cbSize; UINT fMask; int nMin; int nMax; UINT nPage; int nPos; int nTrackPos; } SCROLLINFO, *LPSCROLLINFO;

Trong cbSize quy nh kch thc cu trc, fMask quy nh kiu tham s ca thanh cun bao gm SIF_ALL, SIF_RANGE, SIF_POS, SIF_PAGE, SIF_TRACKPOS, nMin v nMax quy nh gii hn ca con chy, nPage quy nh kch thc trang dch con chy, nPos quy nh v tr con chy, nTrackPos b qua trong hm SetScrollInfo() ny.

V d 3.9
Lp trnh to mt hp thoi nhp vo 3 s a,b,c. Thc hin gii phng trnh a.x2 + b.x + c = 0. Hp thoi cng l mt ca s do vy ta s ly hp thoi lm ca s chnh ca chng trnh, khi trong chng trnh khng cn lp CMyWin nh trc thay bng lp CMyDialog dn xut t lp CDialog v trong hm InitInstance() ca lp CMyApp ta to mt hp thoi v gi lnh DoModal() tng ng hin hp thoi. Khai bo hp thoi trong tp RC nh sau:
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 241, 114 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Vi du 09 - Chuong 03" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,101,93,50,14 LTEXT "He so a",IDC_STATIC,26,7,30,11

100

LTEXT "He so b",IDC_STATIC,26,22,30,11 LTEXT "He so c",IDC_STATIC,26,39,30,11 EDITTEXT IDC_EDIT1,61,7,41,13,ES_AUTOHSCROLL EDITTEXT IDC_EDIT2,61,22,41,13,ES_AUTOHSCROLL EDITTEXT IDC_EDIT3,61,39,41,13,ES_AUTOHSCROLL PUSHBUTTON "Giai PT",IDC_BUTTON1,147,27,52,14 LTEXT "Nghiem cua phuong trinh",IDC_STATIC,26,58,88,11 EDITTEXT IDC_EDIT4,38,70,185,13,ES_AUTOHSCROLL END

Ni dung chng trnh nh sau:


#include<afxwin.h> #include<math.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyDialog : public CDialog { public: CMyDialog(UINT ID, CWnd *owner=NULL) : CDialog(ID,owner) {} BOOL OnInitDialog(); afx_msg void OnGiaiPT(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyDialog , CDialog ) ON_COMMAND( IDC_BUTTON1, OnGiaiPT ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyDialog(IDD_DIALOG1,NULL); int kq=((CMyDialog *)m_pMainWnd)->DoModal(); return TRUE; } BOOL CMyDialog::OnInitDialog()

101

{ return TRUE; } void CMyDialog::OnGiaiPT() { double a,b,c,d,x1,x2; char s[20]; CEdit *ed; ed=(CEdit*)GetDlgItem(IDC_EDIT1); ed->GetWindowText(s,20); a=atof(s); ed=(CEdit*)GetDlgItem(IDC_EDIT2); ed->GetWindowText(s,20); b=atof(s); ed=(CEdit*)GetDlgItem(IDC_EDIT3); ed->GetWindowText(s,20); c=atof(s); ed=(CEdit*)GetDlgItem(IDC_EDIT4); d=b*b-4*a*c; if (a==0) sprintf(s,"He so a bang 0, khong thuc hien"); else { if (d<0) sprintf(s,"Phuong trinh vo nghiem"); else { if (d==0) sprintf(s,"PT co nghiem kep x1=x2=%-0.5lf",-b/(a*2)); else { x1=(-b+sqrt(d))/(2*a); x2=(-b-sqrt(d))/(2*a); sprintf(s,"PT co 2 nghiem x1=%-0.5lf & x2=%-0.5lf",x1,x2); } } } ed->SetWindowText(s); }

102

Kt qu chng trnh khi chy th l:

V d 3.10
Lp trnh to mt hp thoi c 3 thanh cun chn mu t hp cho nn ca mt iu khin text. Khai bo hp thoi trong tp RC nh sau:
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 248, 162 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Vi du 10 - Chuong 03" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,104,141,50,14 SCROLLBAR IDC_SCROLLBAR1,40,24,173,13 SCROLLBAR IDC_SCROLLBAR2,40,41,173,13 SCROLLBAR IDC_SCROLLBAR3,40,60,173,13 RTEXT "RED",IDC_STATIC,7,24,29,11 RTEXT "GREEN",IDC_STATIC,7,41,29,11 RTEXT "BLUE",IDC_STATIC,7,60,29,11 CTEXT "Color",IDC_STATIC1,40,78,194,55,WS_BORDER EDITTEXT IDC_EDIT1,217,24,18,13,ES_CENTER | ES_AUTOHSCROLL EDITTEXT IDC_EDIT2,217,42,18,13,ES_CENTER | ES_AUTOHSCROLL EDITTEXT IDC_EDIT3,217,60,18,13,ES_CENTER | ES_AUTOHSCROLL END

Ni dung chnh ca chng trnh nh sau:

103

#include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyDialog : public CDialog { private: int Red,Green,Blue; public: CMyDialog(UINT ID, CWnd *owner=NULL) : CDialog(ID,owner) {} afx_msg void OnHScroll(UINT Kieu,UINT Pos,CScrollBar *pS); BOOL OnInitDialog(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyDialog , CDialog ) ON_WM_HSCROLL() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyDialog(IDD_DIALOG1,NULL); int kq=((CMyDialog *)m_pMainWnd)->DoModal(); return TRUE; } BOOL CMyDialog::OnInitDialog() { CScrollBar *s; SCROLLINFO sif; sif.cbSize=sizeof(SCROLLINFO); sif.fMask=SIF_ALL; sif.nMax=255; sif.nMin=0; sif.nPage=10; sif.nPos=0; s = (CScrollBar*)GetDlgItem(IDC_SCROLLBAR1); s->SetScrollInfo(&sif);

104

s = (CScrollBar*)GetDlgItem(IDC_SCROLLBAR2); s->SetScrollInfo(&sif); s = (CScrollBar*)GetDlgItem(IDC_SCROLLBAR3); s->SetScrollInfo(&sif); Red=Green=Blue=0; return TRUE; } void CMyDialog::OnHScroll(UINT Kieu,UINT Pos,CScrollBar *pS) { HWND hwr,hwg,hwb; GetDlgItem(IDC_SCROLLBAR1,&hwr); GetDlgItem(IDC_SCROLLBAR2,&hwg); GetDlgItem(IDC_SCROLLBAR3,&hwb); switch (Kieu) { case SB_LEFT: if (hwr==pS->m_hWnd) Red=0; else if (hwg==pS->m_hWnd) Green=0; else if (hwb==pS->m_hWnd) Blue=0; break; case SB_RIGHT: if (hwr==pS->m_hWnd) Red=255; else if (hwg==pS->m_hWnd) Green=255; else if (hwb==pS->m_hWnd) Blue=255; break; case SB_LINELEFT: if (hwr==pS->m_hWnd) Red--; else if (hwg==pS->m_hWnd) Green--; else if (hwb==pS->m_hWnd) Blue--; break; case SB_LINERIGHT: if (hwr==pS->m_hWnd) Red++; else if (hwg==pS->m_hWnd) Green++; else if (hwb==pS->m_hWnd) Blue++; break;

105

case SB_PAGELEFT: if (hwr==pS->m_hWnd) Red-=10; else if (hwg==pS->m_hWnd) Green-=10; else if (hwb==pS->m_hWnd) Blue-=10; break; case SB_PAGERIGHT: if (hwr==pS->m_hWnd) Red+=10; else if (hwg==pS->m_hWnd) Green+=10; else if (hwb==pS->m_hWnd) Blue+=10; break; case SB_THUMBTRACK: case SB_THUMBPOSITION: if (hwr==pS->m_hWnd) Red=Pos; else if (hwg==pS->m_hWnd) Green=Pos; else if (hwb==pS->m_hWnd) Blue=Pos; break; } if (Red<0) Red=0; if (Red>255) Red=255; if (Green<0) Green=0; if (Green>255) Green=255; if (Blue<0) Blue=0; if (Blue>255) Blue=255; if (hwr==pS->m_hWnd) pS->SetScrollPos(Red); else if (hwg==pS->m_hWnd) pS->SetScrollPos(Green); else if (hwb==pS->m_hWnd) pS->SetScrollPos(Blue); char s[20]; sprintf(s,"%d",Red); ((CEdit*)GetDlgItem(IDC_EDIT1))->SetWindowText(s); sprintf(s,"%d",Green); ((CEdit*)GetDlgItem(IDC_EDIT2))->SetWindowText(s); sprintf(s,"%d",Blue); ((CEdit*)GetDlgItem(IDC_EDIT3))->SetWindowText(s); CStatic *c = (CStatic*)GetDlgItem(IDC_STATIC1); CDC *dc=c->GetDC(); RECT rt; CBrush br; br.CreateSolidBrush(RGB(Red,Green,Blue)); c->GetClientRect(&rt); dc->SelectObject(&br); dc->FillRect(&rt,&br); }

106

x l thanh cun chng ta phi nh x x l thng ip WM_HSCROLL trong lp CMyDialog, ty theo gi tr tham s hm nh x xc nh v tr mi ca thanh cun v t v tr con chy mi . Hm OnInitDialog() ca lp CMyDialog np chng lp c s CDialog thit lp cc gi tr ban u cho cc iu khin trn hp thoi. Kt qu chng trnh nh sau:

3.5.5. S dng hm DDX v DDV trn cc iu khin


Cc iu khin trn hp thoi cho php ngi dng tc ng thc hin nhp d liu, hoc do chng trnh thng bo kt qu. Tuy nhin d liu trn cc iu khin khng c lu trc tip vo bin nh, hn na chng ta khng th kim tra d liu trc tip khi nhp. Lp trnh MFC cung cp mt k thut thc hin vic ny gi l cc hm DDX - Dialog Data Exchange v DDV - Dialog Data Validation. Hm DDX c th thc hin trn nhiu iu khin cn hm DDV ch thc hin trn mt s iu khin. Hm DDX v DDV thc hin trn cc bin nh phi c nh ngha trong lp hp thoi.

107

Mt s hm DDX v DDV c th thc hin,


Tn hm DDX_Check DDX_Text DDX_Radio DDX_Scroll DDV_MaxChars DDV_MinMaxDouble DDV_MinMaxDWord DDV_MinMaxInt DDV_MinMaxLong DDV_MinMaxUnsigned ngha Qu n l bi n c a checkbox Qu n l bi n xu c a textbox Qu n l bi n c a nt ch n radio Qu n l bi n c a thanh cu n Ki m tra di xu Ki m tra gi tr double Ki m tra gi tr DWORD Ki m tra gi tr integer Ki m tra gi tr long integer Ki m tra gi tr unsigned integer

s dng cc hm DDX v DDV chng ta phi np chng hm DoDataExchange() trong lp hp thoi, n l mt thnh vin hm o c khai bo theo mu sau:
void CWnd :: DoDataExchange ( CDataExchange *Data );

Trong Data l d liu c s dng bi hm DDX v DDV, tham s ny c kiu CDataExchange v chng ta khng th s dng trc tip n. Trong hm np chng ny ngoi vic gi hm c s chng ta s gi cc hm DDX v DDV mong mun. Mi hm DDX v DDV s lin kt mt thnh vin bin nh ca lp hp thoi vi mt iu khin trn , thc hin qua mu khai bo ca hm, v d hai hm sau:
void AFXAPI DDX_Check(CDataExchange *Data,int ID,int &var); void AFXAPI DDV_MaxChars( CDataExchange* pDX, CString const& value, int nChars );

V d 3.11
Lp trnh to hp thoi c hai iu khin Checkbox v Textbox, thc hin s dng hm DDX v DDV kim tra v lu d liu vo bin nh tng ng. Khai bo hp thoi trong tp RC nh sau:
108

IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 228, 106 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Vi du 11 - Chuong 03" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,87,85,50,14 CONTROL "Check1",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,20,74,16 EDITTEXT IDC_EDIT1,94,48,106,16,ES_AUTOHSCROLL END

Trong chng trnh s np chng hm OnOk() hin ni dung cc bin nh sau khi nhp xong. Tp ni dung chng trnh s l:
#include<afxwin.h> #include<math.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyDialog : public CDialog { private: int chk; char txt[15]; public: CMyDialog(UINT ID, CWnd *owner=NULL) : CDialog(ID,owner) {} BOOL OnInitDialog(); void DoDataExchange(CDataExchange *pDX); void OnOk(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; int check; char text[15]; BEGIN_MESSAGE_MAP( CMyDialog , CDialog ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() {

109

m_pMainWnd = new CMyDialog(IDD_DIALOG1,NULL); ((CMyDialog *)m_pMainWnd)->DoModal(); return TRUE; } BOOL CMyDialog::OnInitDialog() { CEdit *ed=(CEdit*)GetDlgItem(IDC_EDIT1); ed->LimitText(10); chk=0; txt[0]='\0'; return TRUE; } void CMyDialog::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); DDX_Check(pDX,IDC_CHECK1,chk); DDX_Text(pDX,IDC_EDIT1,txt,15); } void CMyDialog::OnOk() { CDialog::OnOK(); check = chk; sprintf(text,"%s",txt); EndDialog(IDOK); }

3.6. Cng c to cc ti nguyn ca Visual C


Cc ti nguyn c trnh by trong chng ny c th to bng hai cch, theo khai bo hoc s dng cng c ca Visual C. Vi cch khai bo nh c thc hin phn trc, phn ny trnh by cch to s dng cng ca VisualC vi cc bc nh sau: Bc 1: To tp ti nguyn (Resource files) Chn chc nng File New chn th [Files] chn mc [Resource Script] nhp tn tp ti nguyn tng ng vo [File name] nh du vo [Add to project] Ok.

110

Bc 2: Thm cc ti nguyn M tp ti nguyn to bc 1, bm chut phi vo tp ti nguyn sau khi m chn chc nng Insert,

chn kiu ti nguyn cn thm v chn New. Bc 3: Thc hin chnh sa ti nguyn theo giao din tng ng - To thc n

111

- To nh cursor

- To nh icon

112

- To nh bitmap

- To hp thoi

3.7. Bi tp
Bi tp 3.1
Lp trnh to thc n trn ca s theo cu trc sau:

113

Bi tp 3.2
Lp trnh to mt thc n ng cnh v hin khi bm chut phi ln ca s, thc n c cu trc sau:

Bi tp 3.3
Lp trnh to mt biu tng icon, mt con tr chut cursor v t ln ca s ca chng trnh.

Bi tp 3.4
Lp trnh to mt nh bitmap bt k, cho hin ln ca s khi bm chut phi.

Bi tp 3.5
Lp trnh to hp thoi nhp cc thng tin h tn, nm sinh, qu qun, im thi ca mt hc sinh.

Bi tp 3.6
Lp trnh to hp thoi bn c 8x8 nh sau:

Bi tp 3.7
M rng bi 3.6 trn cho php ngi s dng bm chut vo mt s hin cc du nhn X hoc ch O lun phin nhau trn bn c.

114

Chng 4 X L HA
4.1. C ch ha v h ta ca s
Windows l h iu hnh c giao din ha, lp trnh trn windows l phi lm vic vi ha trn mi thnh phn ca chng trnh. Th vin cc hm ha cung cp cho ngi lp trnh rt ln v kh mm do, vi khun kh ti liu ny chng ti cung cp mt s cch lm vic n gin. H ta ha trn ca s c xc lp bi gc gc tri trn, trc ngang l chiu X tng t tri sang phi v trc dc l chiu Y tng t trn xung. n v chia trn trc X v Y l n v lgic, tng ng vi im nh (pixels), tuy nhin c th thay i n v lgic ny.

Trn ca s ha lun tn ti mt im v hin thi, im ny c th thay i bi cc hm v. Lc hin th ca s im ny t ti gc 0,0 v n khng c hin th trn ca s.

115

4.2. Nt bt v mu t
Cc thnh phn hin trn ca s u c thc hin bng phng php v v t cc hnh nh, c hai i tng quan trng khi v ha l nt bt (pens) v mu t (brushes). Nt bt l i tng to ra t lp CPen dng quy nh nt v cho cc lnh v, mi i tng nt bt bao gm mu sc, rng nt, kiu nt lin, chm, t qung,... Mu t l i tng to ra t lp CBrush dng quy nh mu t cho cc lnh t nn hnh v, mi mu t c kiu t, mu kiu t.

4.2.1. Lp CPen v nt v
CPen :: CPen( int nPenStyle, int nWidth, COLORREF crColor );

- Hm to nt bt vi nPenStyle l kiu nt bt, nWidth l rng, crColor l mu nt bt. Mu nt bt c th dng macro sau thit lp mu ty :
COLORREF RGB( Red , Green , Blue )

Kiu nt bt bao gm cc gi tr sau:


Gi tr PS_SOLID PS_DASH PS_DOT ngha Nt li n Nt g ch Nt ch m Gi tr PS_DASHDOT PS_DASHDOTDOT PS_NULL ngha G ch ch m G ch hai ch m Khng th y

ho c s d ng hm t o nt bt thnh vin sau:


BOOL CPen::CreatePen( int nPenStyle, int nWidth, COLORREF crColor );

4.2.2. Lp CBrush v t nn
CBrush( int nIndex, COLORREF crColor ); CBrush( COLORREF crColor ); CBrush( CBitmap* pBitmap );

- Cc hm to trn thit lp mu t vi cc tham s nIndex quy nh kiu t, mu c quy nh bi crColor v pBitmap quy nh mu t bng mt nh bitmap.
116

Kiu t bao gm cc gi tr sau:


Gi tr HS_BDIAGONAL HS_CROSS HS_DIAGCROSS HS_FDIAGONAL HS_HORIZONTAL HS_VERTICAL ngha Nghing xu ng 45o Ch th p Ch th p nghing Nghing ln 45o K ngang K d c

- Hm to mu t c khai bo theo mu sau


BOOL CBrush :: CreateSolidBrush( COLORREF crColor );

- Hm to mu t theo kiu c sn
BOOL CBrush :: CreateHatchBrush( int Index, COLORREF crColor );

Trong tham s Index quy nh kiu t cn to, gm cc gi tr nh trnh by trn HS_BDIAGONAL, HS_HORIZONTAL,...

4.2.3. Hp thoi chn mu ca h thng


Windows cung cp hp thoi dng chung chn mu t h thng, hp thoi ny c bao gi v x l bi lp CColorDialog trong mt lp ca th vin MFC, chng ta phi to i tng t lp tng ng v gi hm DoModal() sau xc nh gi tr mu c chn qua hm thnh vin. Hm to khai bo i tng l:
CColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd* pParentWnd = NULL );

Cc tham s l mu khi to, kiu chn v ca s cha. Hm ly mu chn l:


COLORREF CColorDialog :: GetColor( ) const;

V d sau s hin th hp thoi vi mu chn ban u l trng, sau mu c chn ly ra lu vo bin m.

117

CColorDialog a( RGB(255,255,255) ); if ( a.DoModal() == IDOK ) m = a.GetColor();

Hm DoModal() s hin hp thoi mu chn, tr v gi tr IDOK nu chng ta bm nt lnh Ok trn hp thoi , ngc li hm tr v IDCANCEL.

4.3. Lp CDC v cc hm v
4.3.1. Gii thiu lp CDC
Nh trnh by trong chng trc v ln ca s chng ta s dng cc lnh v thng qua i tng lp CDC (class device context). i tng CDC c tc dng xc lp b nh trn my ng vi phn ca s s hin trn mn hnh, mi thao tc v u thc hin trn phn b nh gi l b nh mn hnh cho ca s. Khi to ca s chng ta c ngay phn ny, v ta ch cn ly i tng CDC qua hm thnh vin ca ca s nh sau:
CDC* CWnd :: GetDC( );

Trong lp CDC c cc lnh v nh sau: - Chn nt bt v mu t


CPen* CDC :: SelectObject( CPen* pPen ); CBrush* CDC :: SelectObject( CBrush* pBrush );

Hai hm trn cn tham s l i tng nt bt v mu t, tr li nt bt hoc mu t ang c.

4.3.2. Mt s lnh v c bn
- V mt im nh
COLORREF CDC::SetPixel( int x, int y, COLORREF crColor );

Phi a vo ta x,y im cn t v mu cho im . Gi tr tr v l mu c ca im v. - V ng thng


BOOL CDC::LineTo( int x, int y );

118

- Dch chuyn im v hin thi (s khng nhn thy im ny)


CPoint CDC::MoveTo( int x, int y );

Hm tr v gi tr im kiu CPoint, l lp bao ca cu trc im khai bo theo mu sau:


typedef struct tagPOINT { LONG LONG x; y;

} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;

- V hnh cung
BOOL Arc( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd );

Cung tc l mt phn ca elp hoc hnh trn, v hnh cung chng ta phi xc nh cc tham s gm mt hnh ch nht ngoi tip elip hoc hnh trn ca cung , im xc nh ng thng ni vi tm to thnh gc chn cung th nht, im xc nh ng thng ni vi tm to thnh gc chn cung th hai. Xc nh theo hnh v sau:

Ngoi ra c lnh v cung trn theo gc chn cung nh sau:


BOOL AngleArc( int x, int y, int nR, float fS, float fE );

119

Trong x,y l tm ca hnh trn cha cung, nR l bn knh, fS l gc bt u v, fE l gc chn cung cn v.

- V hnh ch nht
BOOL CDC::Rectangle( int x1, int y1, int x2, int y2 ); BOOL CDC::Rectangle( LPCRECT lpRect );

V hnh ch nht c xc nh ta hai im hai gc i din, gc tri trn l x1,y1 v gc phi di l x2,y2. C th xc nh bng kiu RECT mu 2. Hnh ch nht s c t ng t theo kiu t chn sn. Nu cn v hnh ch nht c vt gc bng cung elp ta s dng lnh sau:
BOOL RoundRect( int x1, int y1, int x2, int y2, int x3, int y3 ); BOOL RoundRect( LPCRECT lpRect, POINT point );

Vi gc c vt xc nh bng rng v cao ca elp cn thc hin, l gi tr x3 v y3 hoc tham s point mu 2. V d vi mu v bng 2 lnh sau:
dc->Rectangle(50,50,450,250); dc->RoundRect(50,50,450,250,300,150);

120

- V hnh elp
BOOL CDC::Ellipse( int x1, int y1, int x2, int y2 ); BOOL CDC::Ellipse( LPCRECT lpRect );

Trong x1,y1 v x2,y2 l ta hai im xc nh hnh ch nht ngoi tip elp cn v, hoc xc nh qua cu trc kiu RECT mu 2. Hnh elp s c t theo mu t hin thi. - V hnh qut
BOOL Pie( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ); BOOL Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd );

Trong x1,y1 v x2,y2 xc nh ta hnh ch nht ngoi tip elp cha hnh qut, x3,y3 xc nh im ni tm ca ng gc chn cung th nht v x4,y4 l gc chn cung th 2 (cc tham s ging lnh v cung Arc). y v hnh qut nn s c thm hai ng gc chn cung ng thi c t nn theo mu t hin thi.

V d 4.1
Lp trnh cho php chn chc nng trn thc n v cc hnh c bn nh cc lnh trnh by trn, cho php chn mu v, mu t v kiu t. Khai bo cc hng cung cp cho tp ti nguyn:
#define IDR_MENU1 101 #define ID_THOAT 40001 #define ID_CHONMAUVE_DO 40002 #define ID_CHONMAUVE_XANH 40003 #define ID_CHONMAUVE_VANG 40004 #define ID_CHONMAUVE_TIM 40005 #define ID_CHONMAUTO_DO 40006 #define ID_CHONMAUTO_XANH 40007 #define ID_CHONMAUTO_VANG 40008 #define ID_CHONMAUTO_TIM 40009 #define ID_CHONHINHVE_CHUNHAT 40010 #define ID_CHONHINHVE_TRON 40011 #define ID_CHONHINHVE_ELIP 40012 #define ID_CHONHINHVE_GOCTRON 40013 #define ID_CHONHINHVE_QUAT 40014 #define ID_CHONKIEUTO_DAC 40015

121

#define ID_CHONKIEUTO_GACHNGANG 40016 #define ID_CHONKIEUTO_GACHDOC 40017 #define ID_CHONKIEUTO_LUOIOVUONG 40018 #define ID_CHONKIEUTO_NGHIENG 40019

Khai bo ti nguyn thc n trong tp RC nh sau:


IDR_MENU1 MENU DISCARDABLE BEGIN POPUP "Chon mau ve" BEGIN MENUITEM "Do", ID_CHONMAUVE_DO MENUITEM "Xanh", ID_CHONMAUVE_XANH MENUITEM "Vang", ID_CHONMAUVE_VANG MENUITEM "Tim", ID_CHONMAUVE_TIM END POPUP "Chon mau to" BEGIN MENUITEM "Do", ID_CHONMAUTO_DO MENUITEM "Xanh", ID_CHONMAUTO_XANH MENUITEM "Vang", ID_CHONMAUTO_VANG MENUITEM "Tim", ID_CHONMAUTO_TIM END POPUP "Chon hinh ve" BEGIN MENUITEM "Chu nhat", ID_CHONHINHVE_CHUNHAT MENUITEM "Tron", ID_CHONHINHVE_TRON MENUITEM "Elip", ID_CHONHINHVE_ELIP MENUITEM "Goc tron", ID_CHONHINHVE_GOCTRON MENUITEM "Quat", ID_CHONHINHVE_QUAT END POPUP "Chon kieu to" BEGIN MENUITEM "Dac", ID_CHONKIEUTO_DAC MENUITEM "Gach ngang", ID_CHONKIEUTO_GACHNGANG MENUITEM "Gach doc", ID_CHONKIEUTO_GACHDOC MENUITEM "Luoi o vuong", ID_CHONKIEUTO_LUOIOVUONG MENUITEM "Nghieng", ID_CHONKIEUTO_NGHIENG END MENUITEM "Thoat", ID_THOAT END

122

Ni dung chng trnh nh sau:


#include<afxwin.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: COLORREF mauve,mauto; int kieuto; public: CMyWin(); void OnChonmauve(UINT id); void OnChonmauto(UINT id); void OnChonhinhve(UINT id); void OnChonkieuto(UINT id); void OnThoat(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND_RANGE(ID_CHONMAUVE_DO,ID_CHONMAUVE_TIM,OnChonmauv e) ON_COMMAND_RANGE(ID_CHONMAUTO_DO,ID_CHONMAUTO_TIM,OnChonmaut o) ON_COMMAND_RANGE(ID_CHONHINHVE_CHUNHAT,ID_CHONHINHVE_QUAT,On Chonhinhve) ON_COMMAND_RANGE(ID_CHONKIEUTO_DAC,ID_CHONKIEUTO_NGHIENG,OnC honkieuto) ON_COMMAND(ID_THOAT,OnThoat) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; }

123

CMyWin::CMyWin() { CMenu mn; Create(NULL,"Vi du 01 - Chuong 04"); mn.LoadMenu(IDR_MENU1); SetMenu(&mn); mauto=RGB(255,255,255); kieuto=0; mauve=RGB(0,0,0); } void CMyWin::OnChonmauve(UINT id) { switch (id) { case ID_CHONMAUVE_DO: mauve=RGB(255,0,0);break; case ID_CHONMAUVE_XANH: mauve=RGB(0,0,255); break; case ID_CHONMAUVE_VANG: mauve=RGB(255,255,0);break; case ID_CHONMAUVE_TIM: mauve=RGB(255,0,255);break; } } void CMyWin::OnChonmauto(UINT id) { switch (id) { case ID_CHONMAUTO_DO: mauto = RGB(255,0,0); break; case ID_CHONMAUTO_XANH: mauto = RGB(0,0,255); break; case ID_CHONMAUTO_VANG: mauto = RGB(255,255,0);break; case ID_CHONMAUTO_TIM: mauto = RGB(255,0,255);break; } } void CMyWin::OnChonhinhve(UINT id) { CBrush b;CPen p; CDC *dc=GetDC(); p.CreatePen(PS_SOLID,2,mauve); if (kieuto==0) b.CreateSolidBrush(mauto); else b.CreateHatchBrush(kieuto,mauto); dc->SelectObject(p); dc->SelectObject(b); switch (id) { case ID_CHONHINHVE_CHUNHAT:

124

dc->Rectangle(10,10,100,50); break; case ID_CHONHINHVE_TRON: dc->MoveTo(350,100); dc->AngleArc(300,100,50,0,360); break; case ID_CHONHINHVE_ELIP: dc->Ellipse(10,200,150,300); break; case ID_CHONHINHVE_GOCTRON: dc->RoundRect(250,200,400,300,100,70); break; case ID_CHONHINHVE_QUAT: dc->Pie(450,50,550,150,0,0,0,500); break; } b.DeleteObject(); p.DeleteObject(); } void CMyWin::OnChonkieuto(UINT id) { switch (id) { case ID_CHONKIEUTO_DAC: kieuto=0; break; case ID_CHONKIEUTO_GACHNGANG: kieuto=HS_HORIZONTAL; break; case ID_CHONKIEUTO_GACHDOC: kieuto=HS_VERTICAL; break; case ID_CHONKIEUTO_LUOIOVUONG: kieuto=HS_CROSS; break; case ID_CHONKIEUTO_NGHIENG: kieuto=HS_FDIAGONAL; break; } } // Hm thot kh i chng trnh // void CMyWin::OnThoat() { DestroyWindow(); }

125

Trong chng trnh ny c nh x x l thng ip chn thc n theo nhm, s dng macro ON_COMMAND_RANGE() trong lp ca s CMyWin. Khai bo 3 thnh vin bin nh trong lp CMyWin lu cc gi tr mu v, mu t, kiu t chn cung cp cho lnh v. Hm thnh vin x l thng ip chn cc hnh v ta s dng hai i tng CPen v CBrush, tip theo to nt bt v mu t tng ng ri t vo ca s qua lnh SelectObject() ca lp CDC. Sau khi thc hin xong cc lnh v ta phi xa nt bt v mu t gii phng b nh cho my. Kt qu chng trnh sau khi chn mt s chc nng:

4.4. Ch nh x v khung nhn trn ca s


Cc lnh v qua lp CDC u thc hin trn cc n v ta dng lgc, mc nh n v lgc tng ng vi n v vt l (pixels). Tuy nhin chng ta c th thay i t l ny cho ph hp qu trnh v, ta gi t l ny l ch nh x (mapping modes). Ngoi ra trn ca s theo mc nh s c h trc ta c gc gc tri trn, chiu X l tri sang phi, chiu Y l trn xung di. Cc lnh v ch
126

thc hin trn ta nm trong vng ca s nhn thy gi l khung nhn (viewport). Chng ta c th thay i kch thc khung nhn bng cch nh ngha chiu rng v chiu cao ca ca s, sau khi c khung nhn mi th cc lnh v ch thc hin c trong khung nhn . Ch nh x v khung nhn c thc hin qua lp CDC ca ca s. - t ch nh x n v v
virtual int CDC::SetMapMode( int nMapMode );

Trong nMapMode quy nh ch cn t bao gm cc gi tr sau:


Gi tr MM_HIENGLISH MM_HIMETRIC MM_ISOTROPIC MM_ANISOTROPIC MM_LOENGLISH MM_LOMETRIC MM_TEXT MM_TWIPS ngha M t n v lgic b ng 0.001 inch, tr c x dng sang ph i, tr c y m xu ng d i M t n v lgic b ng 0.01 mm, tr c x dng sang ph i, tr c y m xu ng d i n v lgic b ng v i n v ng i dng gi ng nhau c hai tr c X v Y Theo n v ng i dng t nhng khc nhau gi a hai tr c X v Y M t n v lgic b ng 0.1 mm, tr c x dng sang ph i, tr c y m xu ng d i M t n v lgic b ng 0.01 inch, tr c x dng sang ph i, tr c y m xu ng d i M t n v lgic b ng m t n v v t l pixels B ng 20 i m my in (1/1440 inch)

Hm ny tr v ch nh x trc nu t thnh cng, ngc li tr v gi tr 0. Chng ta thy mc nh l ch MM_TEXT. - nh ngha ca s m rng Chn ch nh x n v l MM_ISOTROPIC cho php chng ta nh ngha li kch thc ca s theo n v lgc. nh ngha di trc X v cao trc Y cho ca s ta s dng hm theo mu sau:
virtual CSize CDC::SetWindowExt( int cx, int cy ); virtual CSize CDC::SetWindowExt( SIZE size );

127

Gi tr cx v cy quy nh rng v cao ca hai trc X, Y tng ng. Khi n v v lgc trn ca s c chia theo hai trc ng vi gi tr cx v cy ny. Hm tr v kch thc trc ca ca s di kiu CSize ca cu trc SIZE nh sau:
typedef struct tagSIZE { LONG cx; LONG cy; } SIZE;

Ch : rng khi thay i kch thc ca s bng lnh trn s khng lm thay i kch thc vt l ca s, ch thay i t l gia n v lgc vi n v vt l l pixels. V d ca s c kch thc vt l l 200x100, sau khi t kch thc lgc l 400x160 th t l s l 200/400=0.5 v 100/160=0.625 (mi n v lgc ng vi 0.5 pixel theo chiu ngang v 0.625 theo chiu dc). - nh ngha khung nhn trn ca s
virtual virtual CSize CSize CDC::SetViewportExt( int cx, int cy ); CDC::SetViewportExt( SIZE size );

Gi tr cx v cy quy nh rng v cao ca khung nhn cn t, hoc bi tham s size theo mu 2. Hm tr v gi tr khung nhn trc . Lnh ny ch thc hin c khi ch nh x kiu ngi dng l MM_ISOTROPIC. Chng ta c th nh ngha khung nhn vi kch thc bt k v mi lnh v ch thc hin c vi ta trong khung nhn . Trng hp mun lnh v ch thc hin mt phn trn ca s th thc hin lnh ny xc lp, lnh ny phi thc hin sau lnh t ch nh x n v. - t gc ta lgc cho khung nhn Mc nh gc ta lgc gc tri trn, tuy nhin chng ta c th thay i gc ny bi lnh sau:
virtual CPoint CDC::SetViewportOrg( int x, int y );

128

virtual

CPoint

CDC::SetViewportOrg( POINT point );

Ta gc mi cn t quy nh bi tham s x v y hoc gi tr point theo mu 2. Hm tr v ta gc trc qua i tng CPoint. Ch : Cc lnh SetWindowExt() v SetViewportExt() ch c tc dng khi chng ta t ch nh x l MM_ISOTROPIC hoc MM_ANISOTROPIC, v vy sau khi t ch ny chng ta phi gi hai hm trn mi thc hin cc lnh v c. - Chuyn i gia n v lgc v vt l Mc nh mi lnh v u thc hin theo n v lgc, tuy nhin khi thc hin trn thit b vt l mn hnh th my s t ng chuyn thnh n v pixels. Trong mt s trng hp chng ta mun chuyn i gia hai n v ny s dng hai mu hm sau:
void void void void void void CDC::DPtoLP( LPPOINT lpPoints, int nCount = 1 ) const; CDC::DPtoLP( LPRECT lpRect ) const; CDC::DPtoLP( LPSIZE lpSize ) const; CDC::LPtoDP( LPPOINT lpPoints, int nCount = 1 ) const; CDC::LPtoDP( LPRECT lpRect ) const; CDC::LPtoDP( LPSIZE lpSize ) const;

Trong cc tham s lpPoints, lpRect, lpSize xc nh ta im, ta khung, kch thc cn chuyn. Tham s nCount cho bit cn chuyn bao nhiu im trong tham s lpPoints. Cc hm DPtoLP() thc hin chuyn t n v vt l sang n v lgic (Device Point to Logical Point), ngc li cc hm LPtoDP() chuyn t lgc sang vt l.

V d 4.2
Lp trnh v mt hnh ch nht, 4 gc v 4 hnh trn nh. Sau cho php thay i nh x n v, thay i khung nhn, thay i gc ta . Ta s dng mt hp thoi chn cc tham s thay i theo yu cu trn. Cc ti nguyn thc n, hp thoi khai bo nh sau:

129

// Dialog IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 249, 98 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Chon tham so de ve" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,63,69,50,14 PUSHBUTTON "Cancel",IDCANCEL,129,69,50,14 LTEXT "Che do anh xa don vi ve",IDC_STATIC,17,14,86,11 COMBOBOX IDC_COMBO1,104,14,95,20,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "Chon khung nhin CX=",IDC_STATIC,16,29,73,11 EDITTEXT IDC_EDIT1,89,29,26,12,ES_AUTOHSCROLL LTEXT "CY=",IDC_STATIC,121,29,16,11 EDITTEXT IDC_EDIT2,139,29,26,12,ES_AUTOHSCROLL LTEXT "Goc toa do X=",IDC_STATIC,16,43,73,11 EDITTEXT IDC_EDIT3,89,43,26,12,ES_AUTOHSCROLL LTEXT "Y=",IDC_STATIC,121,43,16,11 EDITTEXT IDC_EDIT4,139,43,26,12,ES_AUTOHSCROLL END // Menu IDR_MENU1 MENU DISCARDABLE BEGIN MENUITEM "Chon tham so", ID_CHONTHAMSO MENUITEM "Ve hinh", ID_VEHINH MENUITEM "Thoat", ID_THOAT END

Ni dung chng trnh nh sau:


#include<afxwin.h> #include"resource.h" char mapmodes[][30]={ "MM_HIMETRIC","MM_ISOTROPIC", "MM_LOENGLISH","MM_TEXT","MM_TWIPS"}; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: int MM; int CX,CY,GX,GY;

130

public: CMyWin(); void OnChonthamso(); void OnVehinh(); void OnThoat(); DECLARE_MESSAGE_MAP() }; class CMyDialog : public CDialog { public: CMyDialog(UINT id,CWnd *ow) : CDialog(id,ow) {} BOOL OnInitDialog(); void OnOK(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND(ID_CHONTHAMSO,OnChonthamso) ON_COMMAND(ID_VEHINH,OnVehinh) ON_COMMAND(ID_THOAT,OnThoat) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP( CMyDialog , CDialog ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } //implement of class for main's window CMyWin::CMyWin() { CMenu mn; Create(NULL,"Vi du 02 - Chuong 04"); mn.LoadMenu(IDR_MENU1); SetMenu(&mn); MM=3; RECT rt; GetClientRect(&rt); CX=rt.right-rt.left; CY=rt.bottom-rt.top;

131

GX=0;GY=0; } void CMyWin::OnChonthamso() { CMyDialog d(IDD_DIALOG1,this); d.DoModal(); } void CMyWin::OnVehinh() { CDC *dc=GetDC(); switch (MM) { case 0: dc->SetMapMode(MM_HIMETRIC);break; case 1: dc->SetMapMode(MM_ISOTROPIC);break; case 2: dc->SetMapMode(MM_LOENGLISH);break; case 3: dc->SetMapMode(MM_TEXT);break; case 4: dc->SetMapMode(MM_TWIPS);break; default: dc->SetMapMode(MM_TEXT);break; } dc->SetMapMode(MM); if (MM==1) dc->SetWindowExt(CX,CY); else dc->SetViewportExt(CX,CY); dc->SetViewportOrg(GX,GY); CPen p; p.CreatePen(PS_SOLID,3,RGB(255,0,0)); CBrush b; b.CreateSolidBrush(RGB(0,0,255)); dc->SelectObject(&p); dc->SelectObject(&b); dc->Rectangle(-50,-50,250,150); dc->MoveTo(-20,-50); dc->AngleArc(-50,-50,30,0,360); dc->MoveTo(280,-50); dc->AngleArc(250,-50,30,0,360); dc->MoveTo(-20,150); dc->AngleArc(-50,150,30,0,360); dc->MoveTo(280,150); dc->AngleArc(250,150,30,0,360); } void CMyWin::OnThoat() { DestroyWindow(); } //implement of class for dialog BOOL CMyDialog::OnInitDialog() { CMyWin *mw = (CMyWin*)GetParent(); CComboBox *cb = (CComboBox*)GetDlgItem(IDC_COMBO1); for (int i=0;i<5;i++) cb->AddString(mapmodes[i]);

132

cb->SetCurSel(mw->MM); char s[20]; CEdit *ed; ed = (CEdit*)GetDlgItem(IDC_EDIT1); sprintf(s,"%d",mw->CX); ed->SetWindowText(s); ed = (CEdit*)GetDlgItem(IDC_EDIT2); sprintf(s,"%d",mw->CY); ed->SetWindowText(s); ed = (CEdit*)GetDlgItem(IDC_EDIT3); sprintf(s,"%d",mw->GX); ed->SetWindowText(s); ed = (CEdit*)GetDlgItem(IDC_EDIT4); sprintf(s,"%d",mw->GY); ed->SetWindowText(s); return TRUE; } void CMyDialog::OnOK() { CMyWin *mw = (CMyWin*)GetParent(); CComboBox *cb = (CComboBox*)GetDlgItem(IDC_COMBO1); mw->MM = cb->GetCurSel(); char s[20]; CEdit *ed; ed = (CEdit*)GetDlgItem(IDC_EDIT1); ed->GetWindowText(s,20); mw->CX=atoi(s); ed = (CEdit*)GetDlgItem(IDC_EDIT2); ed->GetWindowText(s,20); mw->CY=atoi(s); ed = (CEdit*)GetDlgItem(IDC_EDIT3); ed->GetWindowText(s,20); mw->GX=atoi(s); ed = (CEdit*)GetDlgItem(IDC_EDIT4); ed->GetWindowText(s,20); mw->GY=atoi(s); CDialog::OnOK(); }

Hp thoi cho php chn ch nh x n v, nhp kch thc khung nhn v gc ta . Nu chn ch nh x l MM_ISOTROPIC th kch thc khung nhn thnh kch thc lgc ca s. Ba tham s ny lu trong cc thnh vin bin nh ca lp CMyWin, do vy trong lp CMyDialog phi s dng lnh GetParent() tr v ca s chng trnh truy nhp cc thnh vin .

133

Nu chn tham s nh sau:

Kt qu chng trnh s l:

V d 4.3
Lp trnh v th hm s sin ln ca s, cho php phng to thu nh bng cch bm chut tri v phi. Ni dung chng trnh s l:
#include<afxwin.h> #include<math.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd

134

{ private: double Tyle,DX; public: CMyWin(); afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags,CPoint point); afx_msg void OnRButtonDown(UINT nFlags,CPoint point); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 03 - Chuong 04"); Tyle=5; DX=1; } void CMyWin::OnPaint() { CDC *dc = GetDC(); CPen p; p.CreatePen(PS_SOLID,1,RGB(255,0,0)); int GX,GY; RECT rt; GetClientRect(&rt); GX=(rt.right-rt.left)/2; GY=(rt.bottom-rt.top)/2; dc->SetViewportOrg(GX,GY); dc->SelectObject(&p);

135

dc->MoveTo(0,GY); dc->LineTo(0,-GY); dc->LineTo(-5,-GY+7); dc->MoveTo(0,-GY); dc->LineTo(5,-GY+7); dc->MoveTo(-GX,0); dc->LineTo(GX,0); dc->LineTo(GX-5,7); dc->MoveTo(GX,0); dc->LineTo(GX-5,-7); p.DeleteObject(); p.CreatePen(PS_SOLID,1,RGB(0,0,255)); dc->SelectObject(&p); double x=-GX; dc->MoveTo(x*Tyle,-sin(x)*Tyle); while (x<GX) { x+=DX; dc->LineTo(x*Tyle,-sin(x)*Tyle); } p.DeleteObject(); } void CMyWin::OnLButtonDown(UINT nFlags,CPoint point) { Tyle+=0.5; DX=DX*0.9; Invalidate(); } void CMyWin::OnRButtonDown(UINT nFlags,CPoint point) { Tyle-=0.5; DX=DX*1.1; Invalidate(); }

Trong chng trnh ny c s dng thng ip WM_PAINT v hnh ln ca s, thng ip c sinh ra khi c s tc ng thay i trn ca s v chng ta s v li th sin. Hm x l thng ip l OnPaint() trong lp CMyWin. Lp CMyWin c thm 2 thnh vin Tyle v DX quy nh t l v v bc tng ca gi tr x khi v th. Hai gi tr ny s thay i ngc chiu nhau trong 2 hm x l thng ip WM_LBUTTONDOWN v WM_RBUTTONDOWN tng ng l OnLButtonDown() v OnRButtonDown().

136

Kt qu khi thu nh th sin:

Kt qu khi phng to:

4.5. X l ha cao cp v ca s o
Cc lnh v ln ca s qua CDC s thc hin trc tip trn ca s v chng ta c th thc hin cc lnh v ny bt k thi im s kin no trn ca s. Tuy nhin mi s thay i ca ca s s lm mt cc hnh v trn bi khi thng ip WM_PAINT c gi ti v thc hin hm OnPaint(). C hai phng php khi phc li cc hnh v trn ca s l: thc hin mi thao tc v vo trong hm OnPaint() (nh v d trn) hoc s dng ca s o (virtual window). Ca s o l s dng mt vng b nh tng ng vi ca s hin th, mi thao tc v c thc hin trn vng b nh v chp vo ca s khi cn (thng l trong hm OnPaint()). Cc bc thc hin to ca s o nh sau:
137

Bc 1: Khai bo cc bin nh
CDC m_memDC; CBitmap m_bmp; CBrush m_bkbrush;

i tng m_memDC kiu CDC lu ng cnh thit b ca ca s o cn to, m_bmp kiu CBitmap lu nh bitmap cho ca s o, m_bkbrush kiu CBrush quy nh kiu t cho ca s o. Bc 2: To nh bitmap cho vic lu ca s o
maxX = GetSystemMetrics(SM_CXSCREEN); maxY = GetSystemMetrics(SM_CYSCREEN); CClientDC DC(this); m_memDC.CreateCompatibleDC(&DC); m_bmp.CreateCompatibleBitmap(&DC, maxX, maxY); m_memDC.SelectObject(&m_bmp);

Hai lnh u xc nh ln ca mn hnh theo chiu ngang v dc lu vo hai bin maxX v maxY, hai gi tr ny cung cp cho lnh to nh bitmap sau . Lnh CClientDC DC(this) phi thc hin trong lp ca s cn to ca s o tng ng to i tng DC thuc lp CClientDC, vi tham s hm to l this cho bit xc nh DC ca ca s hin hnh. Lnh to ng cnh thit b ca s o thc hin theo mu sau:
virtual BOOL CDC::CreateCompatibleDC( CDC* pDC );

V ca s o lun gn vi mt ca s tht nn lnh to ny cn phi xc nh mt CDC ca ca s. Lnh to nh bitmap ng vi ca s o c mu sau:


BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );

Tham s pDC quy nh ng cnh thit b ca s tht, nWidth v nHeight quy nh kch thc rng v chiu cao to bitmap, kch thc ny tnh bng pixels. Chng ta a vo hai gi tr maxX v maxY nh trn s to nh bitmap c kch thc ti a bng c mn hnh.

138

Cui cng lnh t nh bitmap vo trong ng cnh thit b ca s o nh sau:


CBitmap* CDC :: SelectObject( CBitmap* pBitmap );

Hm tr v gi tr nh bitmap trc , tham s pBitmap quy nh nh bitmap mi cn t cho ng cnh thit b. Bc 3: To nn cho ca s o
m_bkbrush.CreateStockObject(WHITE_BRUSH); m_memDC.SelectObject(&m_bkbrush); m_memDC.PatBlt(0,0,maxX,maxY,PATCOPY);

Lnh u to mt mu nn t mu trng, s dng hm to cc i tng dng GDI (graphic device interface) nh CPen, CBrush, CFont,... c nh ngha trong h thng. Mu khai bo hm nh sau:
BOOL CGdiObject :: CreateStockObject( int nIndex );

Trong tham s nIndex quy nh kiu i tng s to ra nh WHITE_BRUSH, BLACK_PEN, BLACK_BRUSH, SYSTEM_FONT,... Sau khi to c mu nn t chng ta t vo ng cnh thit b ca s o bng lnh SelectObject(). Cui cng to mu bit trn ng cnh thit b, mu to ra c kt hp gia mu nn t chn v mu c sn trn ng cnh .
BOOL PatBlt( int x, int y, int nWidth, int nHeight, DWORD dwRop );

Gi tr dwDrop quy nh kiu kt hp gia hai mu bao gm:


Gi tr PATCOPY PATINVERT DSTINVERT BLACKNESS WHITENESS ngha Chp m u t i nh bitmap S d ng php XOR o ng c nh bitmap t nh mu en t nh mu tr ng

Ch : Mi thao tc v u thc hin trn ca s o m_memDC, hin ln ca s tht nhn thy chng ta thc hin trong hm OnPaint() ca thng ip

139

WM_PAINT ca lp ca s. Lnh chp nh t ca s o sang ca s tht nh sau:


BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );

Trong x,y l ta ch gc tri trn cn chp nh ti, nWidth v nHeight l kch thc nh cn chp, pSrcDC l ng cnh ca s o, xSrc,ySrc l ta nh trn ca s o cn thc hin chp, dwDrop l ch chp bao gm:
Gi tr BLACKNESS DSINVERT MERGECOPY MERGEPAINT NOTSRCCOPY PATCOPY PATINVERT SRCAND SRCCOPY ngha t nh chp t i l mu en o ng c nh bitmap ch S d ng php AND S d ng php OR Chp nh o ng c c a nh g c Chp m u t i nh ch S d ng php XOR gi a m u v i nh ch S d ng php AND Chp nh bitmap g c vo nh ch

V d 4.4
Lp trnh cho php v cc hnh c bn trn ca s bng chut, c thc n chn mu v, chn mu t, chn hnh v. Khi chn chc nng v hnh v x l thng ip chut v hnh mong mun ln ca s tht, sau khi v xong hnh chng ta mi thc hin v vo ca s o, cui cng chp ca s o ln ca s tht. Ni dung tp khai bo thc n:
IDR_MENU1 MENU DISCARDABLE BEGIN POPUP "Chon mau ve" BEGIN MENUITEM "Do", MENUITEM "Xanh", MENUITEM "Vang", MENUITEM "Tim", END

ID_CHONMAUVE_DO ID_CHONMAUVE_XANH ID_CHONMAUVE_VANG ID_CHONMAUVE_TIM

140

POPUP "Chon mau to" BEGIN MENUITEM "Do", MENUITEM "Xanh", MENUITEM "Vang", MENUITEM "Tim", END POPUP "Chon hinh ve" BEGIN MENUITEM "Chu nhat", MENUITEM "Elip", MENUITEM "Duong thang", MENUITEM "Xoa tat ca", END MENUITEM "Thoat", END

ID_CHONMAUTO_DO ID_CHONMAUTO_XANH ID_CHONMAUTO_VANG ID_CHONMAUTO_TIM

ID_CHONHINHVE_CHUNHAT ID_CHONHINHVE_ELIP ID_CHONHINHVE_DUONGTHANG ID_CHONHINHVE_XOATATCA ID_THOAT

Ni dung tp chng trnh:


#include<afxwin.h> #include "resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CDC m_memDC; CBitmap m_bmp; CBrush m_bkbrush; int maxX,maxY,hinhve; CPoint oldPoint; CPen p; CBrush b; public: CMyWin(); afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags,CPoint point);

141

afx_msg void OnLButtonUp(UINT nFlags,CPoint point); afx_msg void OnMouseMove(UINT nFlags,CPoint point); void OnChooseCommand(UINT id); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_COMMAND_RANGE( ID_CHONMAUVE_DO , ID_THOAT , OnChooseCommand ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { CMenu mn; Create(NULL,"Vi du 04 - Chuong 04"); mn.LoadMenu(IDR_MENU1); SetMenu(&mn); p.CreatePen(PS_SOLID,1,RGB(0,0,0)); b.CreateSolidBrush(RGB(0,0,0)); maxX = GetSystemMetrics(SM_CXSCREEN); maxY = GetSystemMetrics(SM_CYSCREEN); CClientDC DC(this); m_memDC.CreateCompatibleDC(&DC); m_bmp.CreateCompatibleBitmap(&DC,maxX,maxY); m_memDC.SelectObject(&m_bmp); m_bkbrush.CreateStockObject(WHITE_BRUSH); m_memDC.SelectObject(&m_bkbrush);

142

m_memDC.PatBlt(0,0,maxX,maxY,PATCOPY); hinhve=3; //duong thang } void CMyWin::OnPaint() { CPaintDC DC(this); DC.BitBlt(0,0,maxX,maxY,&m_memDC,0,0,SRCCOPY); } void CMyWin::OnLButtonDown(UINT nFlags,CPoint point) { oldPoint=point; } void CMyWin::OnLButtonUp(UINT nFlags,CPoint point) { m_memDC.SelectObject(&b); m_memDC.SelectObject(&p); switch(hinhve) { case 1: m_memDC.Rectangle(oldPoint.x,oldPoint.y,point.x,point.y); break; case 2: m_memDC.Ellipse(oldPoint.x,oldPoint.y,point.x,point.y); break; case 3: m_memDC.MoveTo(oldPoint.x,oldPoint.y); m_memDC.LineTo(point.x,point.y); break; } InvalidateRect(NULL); } void CMyWin::OnChooseCommand(UINT id) { switch (id) { case ID_THOAT: DestroyWindow(); break; case ID_CHONMAUVE_DO: p.DeleteObject(); p.CreatePen(PS_SOLID,1,RGB(255,0,0)); break;

143

case ID_CHONMAUVE_XANH: p.DeleteObject(); p.CreatePen(PS_SOLID,1,RGB(0,0,255)); break; case ID_CHONMAUVE_VANG: p.DeleteObject(); p.CreatePen(PS_SOLID,1,RGB(255,255,0)); break; case ID_CHONMAUVE_TIM: p.DeleteObject(); p.CreatePen(PS_SOLID,1,RGB(255,0,255)); break; case ID_CHONMAUTO_DO: b.DeleteObject(); b.CreateSolidBrush(RGB(255,0,0)); break; case ID_CHONMAUTO_XANH: b.DeleteObject(); b.CreateSolidBrush(RGB(0,0,255)); break; case ID_CHONMAUTO_VANG: b.DeleteObject(); b.CreateSolidBrush(RGB(255,255,0)); break; case ID_CHONMAUTO_TIM: b.DeleteObject(); b.CreateSolidBrush(RGB(255,0,255)); break; case ID_CHONHINHVE_CHUNHAT: hinhve=1; break; case ID_CHONHINHVE_ELIP: hinhve=2; break; case ID_CHONHINHVE_DUONGTHANG: hinhve=3; break; case ID_CHONHINHVE_XOATATCA: m_memDC.SelectObject(&m_bkbrush);

144

m_memDC.PatBlt(0,0,maxX,maxY,PATCOPY); InvalidateRect(NULL); break; } } void CMyWin::OnMouseMove(UINT nFlags,CPoint point) { if (nFlags!=MK_LBUTTON) return; CDC *dc=GetDC(); dc->SelectObject(&p); dc->SelectObject(&b); dc->MoveTo(oldPoint); switch (hinhve) { case 1: dc->Rectangle(oldPoint.x,oldPoint.y,point.x,point.y); break; case 2: dc->Ellipse(oldPoint.x,oldPoint.y,point.x,point.y); break; case 3: dc->LineTo(point); break; } }

Kt qu chng trnh sau khi thc hin v ng thng, ch nht, v ang v hnh elip:

145

4.6. Bi tp
Bi tp 4.1
Lp trnh v ln ca s bn c vua 8x8 c mu .

Bi tp 4.2
Lp trnh v ln ca s li vung kch thc mi l 20x20 pixels, cho php nhn chut vo mt bt k v v cc du X hoc O lun phin nhau (minh ha chi c caro).

Bi tp 4.3
Lp trnh v ln ca s th ca hai hm s cos c mu v sin c mu xanh. V trn on [-5,5] vi t l t tnh phng to y ca s.

Bi tp 4.4
Lp trnh cho php v hnh t do theo bc di chut, nu gi phm SHIFT cho php v ng thng. C th chn mu v qua thc n.

Bi tp 4.5
Lp trnh v mt bnh xe p quay trn ca s, c mt hp thoi chn v tr ca bnh xe, s nan hoa, tc quay, mu sc,...

146

Chng 5 X L VN BN
5.1. C ch hin th vn bn v h ta
Mi thng tin hin th trn ca s u di dng ha k c vn bn, khi hin th vn bn chng ta phi thc hin v cc ch ln ca s. Tuy nhin Windows cung cp cho chng ta hm thc hin qua i tng CDC l hm TextOut().
virtual BOOL TextOut( int x, int y, LPCTSTR lpszString, int nCount );

Lnh TextOut() trn hin xu vn bn lpszString bt u t ta x,y, s k t hin l nCount. H trc ta c gc gc tri trn, chiu ngang l trc X tng t tri sang phi, chiu dc l trc Y tng t trn xung di. H thng n v khi thc hin l n v lgc, theo cc lnh t nh trong chng trc. Lnh t ch cn chnh vn bn hin ra so vi im xut pht a vo trong lnh TextOut() nh sau:
UINT CDC::SetTextAlign( UINT nFlags );

Trong gi tr nFlags quy nh ch cn chnh bao gm cc gi tr sau:


Gi tr TA_CENTER TA_LEFT TA_RIGHT TA_BASELINE TA_BOTTOM ngha Cn gi a trn vn b n Cn tri gi a Cn ph i gi a Theo dng c s c a phng ch Cn tri d i

147

TA_TOP TA_NOUPDATECP TA_UPDATECP

Cn tri trn Khng thay i i m v hi n th i C thay i i m v hi n th i

ngha ca cn chnh so vi im v vn bn cn hin c minh ha nh sau:

5.2. Mu ch v mu nn
Mc nh khi hin vn bn bng lnh TextOut() s c mu ch en v nn trng, c th t li ch mu ny bng cc lnh nh sau:
virtual COLORREF CDC::SetTextColor( COLORREF crColor );

t mu ch vi gi tr mu l crColor c th xc nh mu qua macro RGB(red,green,blue). Tng t hm t mu nn vn bn l:


virtual COLORREF CDC::SetBkColor( COLORREF crColor );

Hai hm trn u tr v gi tr mu trc ca ca s. Khi hin vn bn ln ca s c th thc hin theo hai ch nn khc nhau, l ch OPAQUE (khng trong sut) hoc ch TRANSPARENT (trong sut). ch OPAQUE vn bn hin c mu nn quy nh bng lnh SetBkColor(), cn ch TRANSPARENT vn bn hin khng c nn khi nn s l mu nn ca s. Lnh t ch hin vn bn khai bo theo mu sau:
int CDC::SetBkMode( int nBkMode );

Tham s nBkMode quy nh ch cn t l OPAQUE hoc TRANSPARENT. Hm tr v gi tr ch trc . Mc nh nn ca s hin vn bn ch OPAQUE.


148

V d trn cho thy ch ABC hin ra c mu nn vi ch OPAQUE, s 123 hin khng c mu nn vi ch TRANSPARENT.

5.3. Cu trc ch hin th (text metric)


Cc ch hin ln ca s c kch thc khng ging nhau, hn na khi c phng ch th iu ny li cng r. V d ch "i" c rng nh hn ch "w", ch "a" s thp hn ch "h",... Nh chng ta thy trong son tho vn bn Word, ch khong cch ch, khong cch dng,... rt khc nhau. Ngoi ra c kiu ch, c ch, phng ch,... do hin vn bn ln ca s cho p l phc tp. Windows cung cp cho chng ta c ch kim sot cc kch thc ch hin vn bn ln ca s, cc tham s ny c thit lp trong mt cu trc nh sau:
typedef struct tagTEXTMETRIC { LONG tmHeight; LONG tmAscent; LONG tmDescent; LONG tmInternalLeading; LONG tmExternalLeading; LONG tmAveCharWidth; LONG tmMaxCharWidth; LONG tmWeight; LONG tmOverhang; LONG tmDigitizedAspectX; LONG tmDigitizedAspectY;

149

char tmFirstChar; char tmLastChar; char tmDefaultChar; char tmBreakChar; BYTE tmItalic; BYTE tmUnderlined; BYTE tmStruckOut; BYTE tmPitchAndFamily; BYTE tmCharSet; } TEXTMETRIC;

Cu trc ch c mt ng c s (baseline) xc lp cao v v tr ca ch. V d ng c s ca dng ch c mu nh sau:

ngha ca cc thnh phn trong cu trc trn c m t nh sau: + tmHeight: l cao ca ch c phn trn v di ng c s, + tmAscent: cao pha trn ng c s, + tmDescent: cao pha di ng c s, + tmInternalLeading: khong cch pha trn ch (thng bng 0), + tmExternalLeading: khong cch gia cc dng (thng bng 0), + tmAveCharWidth: rng trung bnh ca ch, + tmMaxCharWidth: rng ti a ca ch, + tmWeight: m nht ca nt ch, + tmOverhang: rng thm vo vi cc kiu phng c bit, + tmDigitizedAspectX: mt ngang ca ch, + tmDigitizedAspectY: mt ng ca ch, + tmFirstChar: k t u tin trong phng ch,

150

+ tmLastChar: k t cui cng trong phng ch, + tmDefaultChar: k t mc nh, + tmBreakChar: k t ngn cch t, + tmItalic: ch in nghin (khc khng), + tmUnderlined: gch chn (khc khng), + tmStruckOut: nt gch b (khc khng), + tmPitchAndFamily: nghing ca phng v h phng ch, + tmCharSet: quy nh b ch. Hu ht cc gi tr trong cu trc ny khng s dng, c hai thnh phn kh quan trng bi v chng c s dng tnh khong cch dc gia cc dng vn bn. Khc vi mn hnh dng text ch c mt kiu phng vi kch thc c nh, Windows c kh nhiu phng ch v cc kch thc rt khc nhau. Mi phng nh ngha cao ca ch v khong cch dc gia cc dng, da vo bit ta hin th cc dng vn bn lin tip nhau. xc nh cu trc ny ca ch ta s dng hm sau:
BOOL CDC::GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;

Cc gi tr thnh phn ca cu trc ch c lu trong tham s lpMetrics, tnh khong cch dng ta cng hai thnh phn tmHeight v tmExternalLeading vi nhau.

Ngoi ra khi hin th vn bn i hi ngi lp trnh phi tnh ton di mt dng vn bn c vt ngoi ca s hay khng, di ny ph thuc vo phng ch, kch thc ch,... Lnh xc nh di dng ch khai bo theo mu sau:
CSize CDC::GetTextExtent( LPCTSTR lpszString, int nCount ) const; CSize CDC::GetTextExtent( const CString& str ) const; 151

Hm tr v kch thc lu trong kiu CSize gm hai thnh phn, cy l cao ca vn bn, cx l di ca dng vn bn . Da vo gi tr cx ny chng ta quyt nh ta hin tip dng hay xung dng trn ca s. C th minh ha cu trc ch hin th trn Windows qua cc thnh phn ca TEXTMETRIC nh sau:

Ngoi ra Windows cung cp hm xc nh kch thc cc thnh phn hin th trn windows, hm c khai bo nh sau:
int GetSystemMetrics( int nIndex );

Trong tham s nIndex quy nh thnh phn cn xc nh kch thc bao gm cc gi tr sau:
Gi tr SM_CXFULLSCREEN SM_CYFULLSCREEN SM_CXICON ngha r ng n n c a s khi phng to cao n n c a s khi phng to r ng bi u t ng

152

SM_CYICON SM_CXSMICON SM_CYSMICON SM_CXSCREEN SM_CYSCREEN

cao bi u t ng r ng bi u t ng thu nh cao bi u t ng thu nh r ng mn hnh cao mn hnh

V d 5.1
Lp trnh hin th cc gi tr tham s ca cu trc ch v kch thc mn hnh, kch thc ca s. Ni dung chng trnh l:
#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnLButtonDown(UINT nFlags,CPoint point); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vidu 01 - Chuong 05"); } void CMyWin::OnLButtonDown(UINT nFlags,CPoint point) { char s[200];

153

int kc,y=0; CSize size; CDC *dc=GetDC(); TEXTMETRIC tm; dc->GetTextMetrics(&tm); kc=tm.tmHeight+tm.tmExternalLeading; sprintf(s,"Do cao chu la : %ld",tm.tmHeight); dc->SetBkColor(RGB(0,0,255)); dc->SetTextColor(RGB(255,255,0)); dc->TextOut(0,y,s,strlen(s)); y=y+kc; sprintf(s,"Van ban tiep tren cung dong."); dc->TextOut(0,y,s,strlen(s)); size = dc->GetTextExtent(s,strlen(s)); sprintf(s,"Xau truoc co do dai la : %ld",size.cx); dc->TextOut(size.cx,y,s,strlen(s)); y=y+kc; size.cx = GetSystemMetrics(SM_CXSCREEN); size.cy = GetSystemMetrics(SM_CYSCREEN); sprintf(s,"Kich thuoc man hinh : %ldx%ld",size.cx,size.cy); dc->TextOut(0,y,s,strlen(s)); y=y+kc; sprintf(s,"Khoang cach giua cac dong van ban la : %ld",kc); dc->TextOut(0,y,s,strlen(s)); }

Kt qu chng trnh l:

Chng trnh x l phm tri chut, thc hin in ln ca s khi bm chut tri vo ca s.

5.4. S dng phng ch


Windows cung cp kh nhiu phng ch hin th ty vo vic thit lp trong h thng phng ch ca my. Chng ta c th s dng phng ch sn c hoc c th to ra phng ch mi ty . Cc phng ch c sn l cc i tng stock c to bi lnh sau:
BOOL 154 CreateStockObject( int nIndex );

Trong tham s nIndex quy nh kiu phng ch cn to i tng tng ng, gm:
Gi tr ANSI_FIXED_FONT ANSI_VAR_FONT DEVICE_DEFAULT_FONT DEFAULT_GUI_FONT OEM_FIXED_FONT SYSTEM_FONT SYSTEM_FIXED_FONT ngha Phng c d c c nh Phng c d c thay i Phng ch m c nh theo thi t b Phng ch c a h p tho i Phng ch OEM Phng ch c a Windows Phng ch Windows phin b n c

Trong chng trnh chn v s dng phng ch c sn kh d dng, chng ta s dng lp CFont thc hin. Trc ht to mt i tng thuc lp , tip theo np phng ch cn chn bng hm CreateStockObject() nh trn. Cn s dng phng ch no ta chn vo ca s bng lnh SelectObject() ca lp CDC.

V d 5.2
Lp trnh hin vn bn theo cc kiu phng ch sn c trong Windows ln ca s. Ni dung chng trnh l:
#include<afxwin.h> // nh ngha cc h ng s cho m c ch n trn th c n ch n #define ID_ANSI_FIXED_FONT 1000 #define ID_ANSI_VAR_FONT 1001 #define ID_DEVICE_DEFAULT_FONT 1002 #define ID_DEFAULT_GUI_FONT 1003 #define ID_OEM_FIXED_FONT 1004 #define ID_SYSTEM_FONT 1005 #define ID_SYSTEM_FIXED_FONT 1006 #define ID_SHOW 1007 #define ID_THOAT 1008 // N i dung chnh c a chng trnh class CMyApp : public CWinApp { public: BOOL InitInstance(); };

155

class CMyWin : public CFrameWnd { private: CMenu mn,pp; CFont font; int y; public: CMyWin(); void OnCommand(UINT id); void ShowText(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND_RANGE( ID_ANSI_FIXED_FONT, ID_THOAT, OnCommand ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vidu 01 - Chuong 05"); mn.CreateMenu(); pp.CreatePopupMenu(); pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_ANSI_FIXED_FONT,"Ansi fixed font"); pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_ANSI_VAR_FONT,"Ansi var font"); pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_DEVICE_DEFAULT_FONT,"Devi ce default font"); pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_DEFAULT_GUI_FONT,"Default GUI font"); pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_OEM_FIXED_FONT,"OEM fixed font"); pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_SYSTEM_FONT,"System font");

156

pp.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_SYSTEM_FIXED_FONT,"System fixed font"); mn.AppendMenu(MF_POPUP , (UINT)pp.m_hMenu ,"Chon font"); mn.AppendMenu(MF_STRING | MF_BYCOMMAND , ID_SHOW , "Xem"); mn.AppendMenu(MF_STRING | MF_BYCOMMAND , ID_THOAT , "Thoat"); SetMenu(&mn); font.CreateStockObject(SYSTEM_FONT); y=200; } void CMyWin::OnCommand(UINT id) { switch (id) { case ID_THOAT: DestroyWindow(); break; case ID_SHOW: ShowText(); break; case ID_ANSI_FIXED_FONT: font.DeleteObject(); font.CreateStockObject(ANSI_FIXED_FONT); y=0; break; case ID_ANSI_VAR_FONT: font.DeleteObject(); font.CreateStockObject(ANSI_VAR_FONT); y=40; break; case ID_DEVICE_DEFAULT_FONT: font.DeleteObject(); font.CreateStockObject(DEVICE_DEFAULT_FONT); y=80; break; case ID_DEFAULT_GUI_FONT: font.DeleteObject();

157

font.CreateStockObject(DEFAULT_GUI_FONT); y=120; break; case ID_OEM_FIXED_FONT: font.DeleteObject(); font.CreateStockObject(OEM_FIXED_FONT); y=160; break; case ID_SYSTEM_FONT: font.DeleteObject(); font.CreateStockObject(SYSTEM_FONT); y=200; break; case ID_SYSTEM_FIXED_FONT: font.DeleteObject(); font.CreateStockObject(SYSTEM_FIXED_FONT); y=240; break; } } void CMyWin::ShowText() { CDC *dc=GetDC(); dc->SetBkMode(OPAQUE); dc->SetBkColor(RGB(0,0,255)); dc->SetTextColor(RGB(255,255,0)); dc->SelectObject(&font); TEXTMETRIC tm; dc->GetTextMetrics(&tm); dc->TextOut(0,y,"Cong hoa xa hoi chu nghia viet nam",34); dc->TextOut(0,y+tm.tmHeight+tm.tmExternalLeading,"Doc lap - Tu do - Hanh phuc",27); }

Trong chng trnh ny s dng cch to thc n bng cu lnh, khng qua nh ngha ti nguyn nn ch cn mt tp CPP duy nht. Tuy nhin chng ta nh ngha cc nh danh mc chn thng qua cc tn bng lnh define nh trn, khng nn s dng s nguyn trc tip trong cc lnh.

158

Kt qu chng trnh l:

Ngoi vic s dng cc phng ch c sn trn Windows chng ta c th to ra cc phng ch ty . S dng i tng lp CFont thc hin bng hm sau:
BOOL CFont :: CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, LPCTSTR lpszFacename );

Cc tham s trong lnh ny c ngha nh sau: + int nHeight: cao ch, nu bng 0 my s ly mc nh, + int nWidth: rng trung bnh ca cc ch, + int nEscapement: gc nghing ca ch theo phng ngang theo , + int nOrientation: gc nghing ca ng c s vi phng ngang,

159

+ int nWeight: m ca ch gm mt trong cc gi tr sau:


FW_DONTCARE FW_ULTRALIGHT FW_REGULAR FW_DEMIBOLD FW_ULTRABOLD FW_THIN FW_LIGHT FW_MEDIUM FW_BOLD FW_BLACK FW_EXTRALIGHT FW_NORMAL FW_SEMIBOLD FW_EXTRABOLD FW_HEAVY

+ BYTE bItalic: ch nghing, + BYTE bUnderline: ch gch chn, + BYTE cStrikeOut: ch c nt gch b, + BYTE nCharSet: b kiu ch gm cc gi tr sau:
ANSI_CHARSET SHIFTJIS_CHARSET SYMBOL_CHARSET DEFAULT_CHARSET OEM_CHARSET

+ BYTE nOutPrecision: quy nh chnh xc ch khi hin ra, bao gm cc gi tr sau:


OUT_CHARACTER_PRECIS OUT_DEFAULT_PRECIS OUT_DEVICE_PRECIS OUT_RASTER_PRECIS OUT_STRING_PRECIS OUT_STROKE_PRECIS OUT_TT_PRECIS

+ BYTE nClipPrecision: gm cc gi tr sau:


CLIP_CHARACTER_PRECIS CLIP_DEFAULT_PRECIS CLIP_ENCAPSULATE CLIP_LH_ANGLES CLIP_MASK CLIP_STROKE_PRECIS CLIP_TT_ALWAYS

+ BYTE nQuality: quy nh cht lng ch hin ra, bao gm cc gi tr:


DEFAULT_QUALITY DRAF_QUALITY PROOF_QUALITY

+ BYTE nPitchAndFamily: bao gm cc gi tr:


DEFAULT_PITCH VARIABLE_PITCH FIXED_PITCH

+ LPCTSTR lpszFacename: tn phng ch, nu bng NULL my s ly mt phng ch thit b mc nh.

160

V d 5.3
Lp trnh hin mt xu "Ha noi - Hue - Sai gon" vi cc tham s ca lnh to phng ch khc nhau trn cc dng khc nhau. Tp khai bo ti nguyn RC l:
// nh ngha cc h ng s trong ti nguyn chng trnh #define IDD_DIALOG1 101 #define IDR_MENU1 103 #define IDC_EDIT_HEIGHT 1000 #define IDC_EDIT_WIDHT 1001 #define IDC_EDIT_ESCAPEMENT 1002 #define IDC_EDIT_ORIENTATION 1003 #define IDC_COMBO_WEIGHT 1004 #define IDC_CHECK_ITALIC 1005 #define IDC_CHECK_UNDERLINE 1014 #define IDC_CHECK_STRIKEOUT 1015 #define IDC_COMBO_CHARSET 1016 #define IDC_COMBO_OUTPRECISION 1017 #define IDC_COMBO_CLIPPRECISION 1018 #define IDC_COMBO_QUALITY 1019 #define IDC_COMBO_PITCHFAMILY 1020 #define IDC_COMBO_FACENAME 1021 #define ID_CHONFONT 40001 #define ID_XEM 40002 #define ID_THOAT 40003 #define ID_XOA 40004 // Dialog - Khai bo h p tho i IDD_DIALOG1 DIALOGEX 0, 0, 325, 133 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Chon cac tham so tao phong chu" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,87,115,50,14 PUSHBUTTON "Cancel",IDCANCEL,165,115,50,14 LTEXT "Height",IDC_STATIC,13,11,49,11,0,WS_EX_STATICEDGE LTEXT "Width",IDC_STATIC,13,26,49,11,0,WS_EX_STATICEDGE EDITTEXT IDC_EDIT_HEIGHT,65,11,91,12,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_EDIT_WIDHT,65,26,91,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Escapement",IDC_STATIC,13,42,49,11,0,WS_EX_STATICEDGE EDITTEXT IDC_EDIT_ESCAPEMENT,65,42,91,12,ES_AUTOHSCROLL | ES_NUMBER LTEXT "Orientation",IDC_STATIC,13,58,49,11,0,WS_EX_STATICEDGE EDITTEXT IDC_EDIT_ORIENTATION,65,58,91,12,ES_AUTOHSCROLL |

161

ES_NUMBER "Weight",IDC_STATIC,13,74,49,11,0,WS_EX_STATICEDGE "Char set",IDC_STATIC,171,11,49,11,0,WS_EX_STATICEDGE "Out precision",IDC_STATIC,171,26,49,11,0, WS_EX_STATICEDGE LTEXT "Clip precision",IDC_STATIC,171,42,49,11,0, WS_EX_STATICEDGE LTEXT "Quality",IDC_STATIC,171,58,49,11,0,WS_EX_STATICEDGE LTEXT "Pitch && family",IDC_STATIC,171,74,49,11,0, WS_EX_STATICEDGE LTEXT "Face name",IDC_STATIC,171,90,49,11,0,WS_EX_STATICEDGE COMBOBOX IDC_COMBO_WEIGHT,65,74,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP CONTROL "Italic",IDC_CHECK_ITALIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,90,31,12 CONTROL "Underline",IDC_CHECK_UNDERLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,90,44,12 CONTROL "Strike out",IDC_CHECK_STRIKEOUT,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,109,90,46,12 COMBOBOX IDC_COMBO_CHARSET,223,11,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_OUTPRECISION,223,26,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_CLIPPRECISION,223,42,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_QUALITY,223,58,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_PITCHFAMILY,223,74,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO_FACENAME,223,90,91,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP END // Dialog Info - Chi ti t cc tham s cho i u khi n trn h p tho i IDD_DIALOG1 DLGINIT BEGIN IDC_COMBO_WEIGHT, 0x403, 12, 0 0x5746, 0x445f, 0x4e4f, 0x4354, 0x5241, 0x0045, IDC_COMBO_WEIGHT, 0x403, 8, 0 0x5746, 0x545f, 0x4948, 0x004e, LTEXT LTEXT LTEXT

162

IDC_COMBO_WEIGHT, 0x403, 14, 0 0x5746, 0x455f, 0x5458, 0x4152, 0x494c, 0x4847, 0x0054, IDC_COMBO_WEIGHT, 0x403, 14, 0 0x5746, 0x555f, 0x544c, 0x4152, 0x494c, 0x4847, 0x0054, IDC_COMBO_WEIGHT, 0x403, 9, 0 0x5746, 0x4c5f, 0x4749, 0x5448, "\000" IDC_COMBO_WEIGHT, 0x403, 10, 0 0x5746, 0x4e5f, 0x524f, 0x414d, 0x004c, IDC_COMBO_WEIGHT, 0x403, 11, 0 0x5746, 0x525f, 0x4745, 0x4c55, 0x5241, "\000" IDC_COMBO_WEIGHT, 0x403, 10, 0 0x5746, 0x4d5f, 0x4445, 0x5549, 0x004d, IDC_COMBO_WEIGHT, 0x403, 12, 0 0x5746, 0x535f, 0x4d45, 0x4249, 0x4c4f, 0x0044, IDC_COMBO_WEIGHT, 0x403, 12, 0 0x5746, 0x445f, 0x4d45, 0x4249, 0x4c4f, 0x0044, IDC_COMBO_WEIGHT, 0x403, 8, 0 0x5746, 0x425f, 0x4c4f, 0x0044, IDC_COMBO_WEIGHT, 0x403, 13, 0 0x5746, 0x455f, 0x5458, 0x4152, 0x4f42, 0x444c, "\000" IDC_COMBO_WEIGHT, 0x403, 13, 0 0x5746, 0x555f, 0x544c, 0x4152, 0x4f42, 0x444c, "\000" IDC_COMBO_WEIGHT, 0x403, 9, 0 0x5746, 0x425f, 0x414c, 0x4b43, "\000" IDC_COMBO_WEIGHT, 0x403, 9, 0 0x5746, 0x485f, 0x4145, 0x5956, "\000" IDC_COMBO_CHARSET, 0x403, 13, 0 0x4e41, 0x4953, 0x435f, 0x4148, 0x5352, 0x5445, "\000" IDC_COMBO_CHARSET, 0x403, 16, 0 0x4544, 0x4146, 0x4c55, 0x5f54, 0x4843, 0x5241, 0x4553, 0x0054, IDC_COMBO_CHARSET, 0x403, 15, 0 0x5953, 0x424d, 0x4c4f, 0x435f, 0x4148, 0x5352, 0x5445, "\000" IDC_COMBO_CHARSET, 0x403, 17, 0 0x4853, 0x4649, 0x4a54, 0x5349, 0x435f, 0x4148, 0x5352, 0x5445, "\000" IDC_COMBO_CHARSET, 0x403, 12, 0 0x454f, 0x5f4d, 0x4843, 0x5241, 0x4553, 0x0054, IDC_COMBO_OUTPRECISION, 0x403, 21, 0 0x554f, 0x5f54, 0x4843, 0x5241, 0x4341, 0x4554, 0x5f52, 0x5250, 0x4345, 0x5349, "\000" IDC_COMBO_OUTPRECISION, 0x403, 18, 0 0x554f, 0x5f54, 0x5453, 0x4952, 0x474e, 0x505f, 0x4552, 0x4943, 0x0053, IDC_COMBO_OUTPRECISION, 0x403, 20, 0 0x554f, 0x5f54, 0x4544, 0x4146, 0x4c55, 0x5f54, 0x5250, 0x4345, 0x5349,

163

0x0020, IDC_COMBO_OUTPRECISION, 0x403, 19, 0 0x554f, 0x5f54, 0x5453, 0x4f52, 0x454b, 0x505f, 0x4552, 0x4943, 0x2053, "\000" IDC_COMBO_OUTPRECISION, 0x403, 19, 0 0x554f, 0x5f54, 0x4544, 0x4956, 0x4543, 0x505f, 0x4552, 0x4943, 0x2053, "\000" IDC_COMBO_OUTPRECISION, 0x403, 15, 0 0x554f, 0x5f54, 0x5454, 0x505f, 0x4552, 0x4943, 0x2053, "\000" IDC_COMBO_OUTPRECISION, 0x403, 18, 0 0x554f, 0x5f54, 0x4152, 0x5453, 0x5245, 0x505f, 0x4552, 0x4943, 0x0053, IDC_COMBO_CLIPPRECISION, 0x403, 22, 0 0x4c43, 0x5049, 0x435f, 0x4148, 0x4152, 0x5443, 0x5245, 0x505f, 0x4552, 0x4943, 0x0053, IDC_COMBO_CLIPPRECISION, 0x403, 10, 0 0x4c43, 0x5049, 0x4d5f, 0x5341, 0x004b, IDC_COMBO_CLIPPRECISION, 0x403, 21, 0 0x4c43, 0x5049, 0x445f, 0x4645, 0x5541, 0x544c, 0x505f, 0x4552, 0x4943, 0x2053, "\000" IDC_COMBO_CLIPPRECISION, 0x403, 20, 0 0x4c43, 0x5049, 0x535f, 0x5254, 0x4b4f, 0x5f45, 0x5250, 0x4345, 0x5349, 0x0020, IDC_COMBO_CLIPPRECISION, 0x403, 16, 0 0x4c43, 0x5049, 0x545f, 0x5f54, 0x4c41, 0x4157, 0x5359, 0x0020, IDC_COMBO_CLIPPRECISION, 0x403, 16, 0 0x4c43, 0x5049, 0x4c5f, 0x5f48, 0x4e41, 0x4c47, 0x5345, 0x0009, IDC_COMBO_QUALITY, 0x403, 16, 0 0x4544, 0x4146, 0x4c55, 0x5f54, 0x5551, 0x4c41, 0x5449, 0x0059, IDC_COMBO_QUALITY, 0x403, 13, 0 0x5244, 0x4641, 0x515f, 0x4155, 0x494c, 0x5954, "\000" IDC_COMBO_QUALITY, 0x403, 14, 0 0x5250, 0x4f4f, 0x5f46, 0x5551, 0x4c41, 0x5449, 0x0059, IDC_COMBO_PITCHFAMILY, 0x403, 14, 0 0x4544, 0x4146, 0x4c55, 0x5f54, 0x4950, 0x4354, 0x0048, IDC_COMBO_PITCHFAMILY, 0x403, 15, 0 0x4156, 0x4952, 0x4241, 0x454c, 0x505f, 0x5449, 0x4843, "\000" IDC_COMBO_PITCHFAMILY, 0x403, 12, 0 0x4946, 0x4558, 0x5f44, 0x4950, 0x4354, 0x0048, 0 END // Menu - Th c n chng trnh IDR_MENU1 MENU DISCARDABLE BEGIN

164

MENUITEM "Chon font", MENUITEM "Xem", MENUITEM "Xoa", MENUITEM "Thoat", END

ID_CHONFONT ID_XEM ID_XOA ID_THOAT

Ni dung tp chng trnh:


#include<afxwin.h> #include"resource.h" struct PARAMETERS { char nHeight[10],nWidth[10],nEscapement[10], nOrientation[10],nWeight[10]; BYTE bItalic,bUnderline,cStrikeOut; char nCharSet[100],nOutPrecision[100], nClipPrecision[100],nQuality[100],nPitchAndFamily[100], lpszFacename[100]; }; int GetValueConst(char *s); class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMenu mn; PARAMETERS pm; int y; public: CMyWin(); void OnChonFont(); void OnXem(); void OnXoa(); void OnThoat(); DECLARE_MESSAGE_MAP() }; class CMyDialog : public CDialog { public:

165

CMyDialog(UINT id,CWnd *ow) : CDialog(id,ow){} BOOL OnInitDialog(); void OnOK(); }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND( ID_CHONFONT, OnChonFont ) ON_COMMAND( ID_XEM, OnXem ) ON_COMMAND( ID_XOA, OnXoa ) ON_COMMAND( ID_THOAT, OnThoat ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vidu 03 - Chuong 05"); mn.LoadMenu(IDR_MENU1); SetMenu(&mn); pm.bItalic=0; pm.bUnderline=0; pm.cStrikeOut=0; strcpy(pm.lpszFacename,"Tahoma"); strcpy(pm.nCharSet,"ANSI_CHARSET"); strcpy(pm.nClipPrecision,"CLIP_DEFAULT_PRECIS"); strcpy(pm.nEscapement,"10"); strcpy(pm.nHeight,"10"); strcpy(pm.nOrientation,"10"); strcpy(pm.nOutPrecision,"OUT_DEFAULT_PRECIS"); strcpy(pm.nPitchAndFamily,"DEFAULT_PITCH"); strcpy(pm.nQuality,"DEFAULT_QUALITY"); strcpy(pm.nWeight,"FW_NORMAL"); strcpy(pm.nWidth,"10"); y=0; } void CMyWin::OnChonFont() { CMyDialog d(IDD_DIALOG1,this); d.DoModal();

166

} void CMyWin::OnXem() { char s[100]="Ha noi - Hue - Sai gon"; CDC *dc=GetDC(); RECT rt; TEXTMETRIC tm; CFont f; f.CreateFont(atoi(pm.nHeight),atoi(pm.nWidth),atoi(pm.nEscapement), atoi(pm.nOrientation),GetValueConst(pm.nWeight),pm.bItalic, pm.bUnderline,pm.cStrikeOut, GetValueConst(pm.nCharSet),GetValueConst(pm.nOutPrecision),GetValueConst(pm.n ClipPrecision), GetValueConst(pm.nQuality),GetValueConst(pm.nPitchAndFamily),pm.lpszFacename); dc->SelectObject(&f); dc->SetBkMode(TRANSPARENT); dc->SetTextColor(RGB(rand()%256,rand()%256,rand()%256)); dc->TextOut(0,y,s); GetClientRect(&rt); dc->GetTextMetrics(&tm); y=y+tm.tmExternalLeading+tm.tmHeight; f.DeleteObject(); } void CMyWin::OnXoa() { InvalidateRect(NULL); y=0; } void CMyWin::OnThoat() { DestroyWindow(); } BOOL CMyDialog::OnInitDialog() { CDialog::OnInitDialog(); PARAMETERS *p = &(((CMyWin*)GetParent())->pm); CComboBox *cb; CEdit *ed; CButton *chk; ed=(CEdit*)GetDlgItem(IDC_EDIT_HEIGHT); ed->SetWindowText(p->nHeight); ed=(CEdit*)GetDlgItem(IDC_EDIT_WIDHT);

167

ed->SetWindowText(p->nWidth); ed=(CEdit*)GetDlgItem(IDC_EDIT_ESCAPEMENT); ed->SetWindowText(p->nEscapement); ed=(CEdit*)GetDlgItem(IDC_EDIT_ORIENTATION); ed->SetWindowText(p->nOrientation); cb=(CComboBox*)GetDlgItem(IDC_COMBO_WEIGHT); cb->SetWindowText(p->nWeight); chk=(CButton*)GetDlgItem(IDC_CHECK_ITALIC); chk->SetCheck(p->bItalic); chk=(CButton*)GetDlgItem(IDC_CHECK_UNDERLINE); chk->SetCheck(p->bUnderline); chk=(CButton*)GetDlgItem(IDC_CHECK_STRIKEOUT); chk->SetCheck(p->cStrikeOut); cb=(CComboBox*)GetDlgItem(IDC_COMBO_CHARSET); cb->SetWindowText(p->nCharSet); cb=(CComboBox*)GetDlgItem(IDC_COMBO_OUTPRECISION); cb->SetWindowText(p->nOutPrecision); cb=(CComboBox*)GetDlgItem(IDC_COMBO_CLIPPRECISION); cb->SetWindowText(p->nClipPrecision); cb=(CComboBox*)GetDlgItem(IDC_COMBO_QUALITY); cb->SetWindowText(p->nQuality); cb=(CComboBox*)GetDlgItem(IDC_COMBO_PITCHFAMILY); cb->SetWindowText(p->nPitchAndFamily); cb=(CComboBox*)GetDlgItem(IDC_COMBO_FACENAME); cb->AddString("Tahoma"); cb->AddString("Arial"); cb->SetWindowText(p->lpszFacename); return TRUE; } void CMyDialog::OnOK() { CDialog::OnOK(); CMyWin *pr = (CMyWin*)GetParent(); PARAMETERS *tm=&(pr->pm); CEdit *ed; CComboBox *cb; CButton *chk; ed=(CEdit*)GetDlgItem(IDC_EDIT_HEIGHT); ed->GetWindowText(tm->nHeight,100); ed=(CEdit*)GetDlgItem(IDC_EDIT_WIDHT);

168

ed->GetWindowText(tm->nWidth,100); ed=(CEdit*)GetDlgItem(IDC_EDIT_ESCAPEMENT); ed->GetWindowText(tm->nEscapement,100); ed=(CEdit*)GetDlgItem(IDC_EDIT_ORIENTATION); ed->GetWindowText(tm->nOrientation,100); cb=(CComboBox*)GetDlgItem(IDC_COMBO_WEIGHT); cb->GetWindowText(tm->nWeight,100); chk=(CButton*)GetDlgItem(IDC_CHECK_ITALIC); tm->bItalic=chk->GetCheck(); chk=(CButton*)GetDlgItem(IDC_CHECK_UNDERLINE); tm->bUnderline=chk->GetCheck(); chk=(CButton*)GetDlgItem(IDC_CHECK_STRIKEOUT); tm->cStrikeOut=chk->GetCheck(); cb=(CComboBox*)GetDlgItem(IDC_COMBO_CHARSET); cb->GetWindowText(tm->nCharSet,100); cb=(CComboBox*)GetDlgItem(IDC_COMBO_OUTPRECISION); cb->GetWindowText(tm->nOutPrecision,100); cb=(CComboBox*)GetDlgItem(IDC_COMBO_CLIPPRECISION); cb->GetWindowText(tm->nClipPrecision,100); cb=(CComboBox*)GetDlgItem(IDC_COMBO_QUALITY); cb->GetWindowText(tm->nQuality,100); cb=(CComboBox*)GetDlgItem(IDC_COMBO_PITCHFAMILY); cb->GetWindowText(tm->nPitchAndFamily,100); cb=(CComboBox*)GetDlgItem(IDC_COMBO_FACENAME); cb->GetWindowText(tm->lpszFacename,100); } int GetValueConst(char *s) { if (strcmp(s,"FW_DONTCARE")==0) return FW_DONTCARE; else if (strcmp(s,"FW_THIN")==0) return FW_THIN; else if (strcmp(s,"FW_EXTRALIGHT")==0) return FW_EXTRALIGHT; else if (strcmp(s,"FW_ULTRALIGHT")==0) return FW_ULTRALIGHT; else if (strcmp(s,"FW_LIGHT")==0) return FW_LIGHT; else if (strcmp(s,"FW_NORMAL")==0) return FW_NORMAL; else if (strcmp(s,"FW_REGULAR")==0) return FW_REGULAR; else if (strcmp(s,"FW_MEDIUM")==0) return FW_MEDIUM; else if (strcmp(s,"FW_SEMIBOLD")==0) return FW_SEMIBOLD; else if (strcmp(s,"FW_DEMIBOLD")==0) return FW_DEMIBOLD; else if (strcmp(s,"FW_BOLD")==0) return FW_BOLD; else if (strcmp(s,"FW_EXTRABOLD")==0) return FW_EXTRABOLD;

169

else if (strcmp(s,"FW_ULTRABOLD")==0) return FW_ULTRABOLD; else if (strcmp(s,"FW_BLACK")==0) return FW_BLACK; else if (strcmp(s,"FW_HEAVY")==0) return FW_HEAVY; else if (strcmp(s,"ANSI_CHARSET")==0) return ANSI_CHARSET; else if (strcmp(s,"DEFAULT_CHARSET")==0) return DEFAULT_CHARSET; else if (strcmp(s,"SYMBOL_CHARSET")==0) return SYMBOL_CHARSET; else if (strcmp(s,"SHIFTJIS_CHARSET")==0) return SHIFTJIS_CHARSET; else if (strcmp(s,"OEM_CHARSET")==0) return OEM_CHARSET; else if (strcmp(s,"OUT_CHARACTER_PRECIS")==0) return OUT_CHARACTER_PRECIS; else if (strcmp(s,"OUT_STRING_PRECIS")==0) return OUT_STRING_PRECIS; else if (strcmp(s,"OUT_DEFAULT_PRECIS")==0) return OUT_DEFAULT_PRECIS; else if (strcmp(s,"OUT_STRING_PRECIS")==0) return OUT_STRING_PRECIS; else if (strcmp(s,"OUT_STROKE_PRECIS")==0) return OUT_STROKE_PRECIS; else if (strcmp(s,"OUT_DEVICE_PRECIS")==0) return OUT_DEVICE_PRECIS; else if (strcmp(s,"OUT_TT_PRECIS")==0) return OUT_TT_PRECIS; else if (strcmp(s,"OUT_RASTER_PRECIS")==0) return OUT_RASTER_PRECIS; else if (strcmp(s,"CLIP_CHARACTER_PRECIS")==0) return CLIP_CHARACTER_PRECIS; else if (strcmp(s,"CLIP_MASK")==0) return CLIP_MASK; else if (strcmp(s,"CLIP_DEFAULT_PRECIS")==0) return CLIP_DEFAULT_PRECIS; else if (strcmp(s,"CLIP_STROKE_PRECIS")==0) return CLIP_STROKE_PRECIS; else if (strcmp(s,"CLIP_TT_ALWAYS")==0) return CLIP_TT_ALWAYS; else if (strcmp(s,"CLIP_LH_ANGLES")==0) return CLIP_LH_ANGLES; else if (strcmp(s,"DEFAULT_QUALITY")==0) return DEFAULT_QUALITY; else if (strcmp(s,"DRAFT_QUALITY")==0) return DRAFT_QUALITY; else if (strcmp(s,"PROOF_QUALITY")==0) return PROOF_QUALITY; else if (strcmp(s,"DEFAULT_PITCH")==0) return DEFAULT_PITCH; else if (strcmp(s,"VARIABLE_PITCH")==0) return VARIABLE_PITCH; else if (strcmp(s,"FIXED_PITCH")==0) return FIXED_PITCH; else return 0; }

Ch : Trong v d ny c s dng hm rand() ly mt s ngu nhin kiu int, khi ta phi chia cho 256 c mt s t 0 n 255. Kt qu chng trnh l:

170

5.5. Ca s o cho vic hin li ni dung


Ni dung hin th trn ca s cho d vn bn hay hnh nh u b mt i khi c s thay i hoc tc ng ln ca s, v khi my u gi thng ip WM_PAINT n ca s v thc hin hm OnPaint(). ni dung c cp nht li chng ta phi thc hin trong hm OnPaint() ny ca lp CMyWin. Nh trong chng 4, phng php tt nht l s dng ca s o. Chng ta to mt vng nh ca s o tng ng vi ca s tht v hin ni dung ln ca s o , khi ch cn chp ca s o ln ca s tht trong hm OnPaint(). Ca s o ng vai tr lu ni dung ca s cn hin trn mn hnh, n l mt vng nh trn my di dng hnh nh bitmap. V vy cn s dng cc i tng ca cc lp sau: CDC, CBitmap, CBrush. Cc bc lm ging nh chng 4, sau y l s minh ha cho quy trnh lm vic vi ca s o cho hin ni dung:

171

Ngoi ra, trong cc ng dng son tho vn bn trn ca s lun c mt thnh phn con tr bn phm dng xc nh v tr tc ng ca ngi dng ln vn bn . Thnh phn ny gi l caret, mc nh ca s hin ln khng c caret nhng chng ta c th to v hin th con tr ny. Hm to con tr bn phm khai bo theo mu sau:
void void void CWnd::CreateCaret( CBitmap* pBitmap ); CWnd::CreateSolidCaret( int nWidth, int nHeight ); CWnd::CreateGrayCaret( int nWidth, int nHeight );

Trong con tr to ra c th s dng mt nh bitmap lm biu tng hnh nh hin th trn ca s, nh ny a vo hm qua tham s pBitmap trn. Hai hm sau to con tr c mt mu hoc en hoc xm, khi ta ch truyn vo rng v chiu cao ca con tr qua hai tham s nWidth v nHeight. Hm hin con tr ln ca s:
void CWnd::ShowCaret( );

hoc lm n con tr

172

void

CWnd::HideCaret( );

Hm t v tr con tr trn ca s:
static void PASCAL CWnd::SetCaretPos( POINT point );

hoc ly v tr con tr nhp nhy hin ti


static CPoint PASCAL CWnd::GetCaretPos( );

Cn tc nhp nhy ca con tr c quy nh bi h thng bng cch thit lp trong control panel.

V d 5.4
Lp trnh hin ta ca chut ln ca s qua ca s o. Kt qu khi nhn chut ln ca s kch thc nh:

Kt qu khi phng to:

173

Kt qu khi ca s ch maximize:

5.6. Bi tp
Bi tp 5.1
Lp trnh hin mt bi th ty ln ca s vi ch mu , khng c nn.

Bi tp 5.2
Lp trnh hin dng h v tn ca bn nm tm ca s trong mi kch thc.

Bi tp 5.3
Lp trnh cho php g cc ch ci v hin ln ca s, khi bm Enter phi vit xung hng. Cc ch ci vit lin tip nhau, khng c ln nhau. Cho php chn phng ch hin th. Thc hin qua ca s o.

Bi tp 5.4
Lp trnh cho hin con tr bn phm (caret) ln ca s v dch chuyn bng cc phm mi tn, hoc bm chut tri ln ca s. Bc dch chuyn bng mt n v pixels.

174

Chng 6 CC IU KHIN NNG CAO


6.1. Khi ng cc iu khin nng cao
Trong chng ny s gii thiu mt phn kh p i vi cc ng dng trn Windows l cc iu khin thng dng (common controls). Trong chng trc cp n cc iu khin chun ca Windows nh: button, checkbox, listbox,... Tuy nhin t Windows 95 tr i c cung cp mt s iu khin kh thun tin i vi ngi dng, rt mm do v linh hat trong tng tc. lp trnh s dng cc iu khin trong chng trnh ta s dng th vin MFC, cc iu khin c th lit k ra nh sau:
i u khi n Animation ComboBoxEx Date/Time Picker Drag List box Header Hot key Image list IP List View Month Calendar Pager Progress bar Property sheet ngha Hi n th cc t p AVI H p danh sch ch n m r ng Xc nh th i gian Danh sch ch n c th ko m c ch n Tiu c t T o phm nng Danh sch hnh nh Cung c p a ch IP Danh sch ch n c bi u t ng Ch n ngy, thng, nm Trang cu n cc i u khi n khc Thanh ch bo ti n trnh th c hi n B ng thu c tnh

175

Rebar Rich Edit Status Tab Toolbar Tooltip Trackbar Tree View Up-down(spin)

Thanh ch a cc i u khi n H p so n th o ph c t p Thanh tr ng thi i u khi n c cc th ch n Thanh nt l nh i u khi n h ng d n tr c ti p Thanh tr t B ng ch n d i d ng cy Tng/gi m

Mi iu khin u c nh ngha qua mt lp trong MFC tng ng, ngi lp trnh phi nm vng cc lp mi to v s dng c cc iu khin ny. Trc ht chng ta phi np tp khai bo th vin AFXCMN.H vo chng trnh bng lnh:
#include<afxcmn.h>

Hn na trong h thng phi c th vin chng trnh tng ng l tp COMCTL32.LIB. Cc ng dng c s dng cc iu khin ny phi gi hm API InitCommonControlsEx() mt ln u tin, hm c khai bo nh sau:
BOOL InitCommonControlsEx( LPINITCOMMONCONTROLSEX lpInitCtrls );

Hm ny thc hin np th vin ng (DLL) vo h thng ang chy thc hin cho cc iu khin, nu thnh cng hm tr li gi tr TRUE v ngc li. Trong tham s ca hm s quy nh iu khin no c khi ng, cu trc INITCOMMONCONTROLSEX ca tham s c khai bo nh sau:
typedef struct tagINITCOMMONCONTROLSEX { DWORD dwSize; DWORD dwICC; } INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX; 176

Thnh phn dwSize cha kch thc ca cu trc, gi tr dwICC quy nh iu khin no c khi ng, l mt trong cc gi tr di y:
Gi tr ICC_ANIMATE_CLASS ICC_BAR_CLASSES ICC_COOL_CLASSES ICC_DATE_CLASSES ICC_HOTKEY_CLASSES ICC_INTERNET_CLASSES ICC_LISTVIEW_CLASSES ICC_PAGESCROLLER_CLASS ICC_PROGRESS_CLASS ICC_TAB_CLASSES ICC_TREEVIEW_CLASSES ICC_UPDOWN_CLASS ICC_USEREX_CLASSES ICC_WIN95_CLASSES ngha Hi n t p AVI Thanh tr ng thi, nt l nh, tr t v tooltip, thanh cng c Thanh ch a cc i u khi n Ch n th i gian Phm nng a ch IP Danh sch bi u t ng v tiu c t Trang cu n cc i u khi n khc Thanh ch bo ti n trnh Th ch n Cy hi n th Tng/gi m H p so n th o Cc i u khi n c a Windows 95

Vy on lnh khi ng cc iu khin s l:


INITCOMMONCONTROLSEX initCtrls; initCtrls.dwSize = sizeof(initCtrls); initCtrls.dwICC = ICC_BAR_CLASSES; InitCommonControlsEx(&initCtrls);

Thng thng chng ta thc hin khi ng cc iu khin ny trong hm khi to ng dng InitInstance() ca lp ng dng CMyApp. Ch : Cc iu khin khi chng ta lm vic qua cc i tng ca lp tng ng s c vai tr nh cc ca s v chng s l cc ca s con nm bn trong ca s chng trnh. Tt c cc lp ng vi cc iu khin u dn xut t lp CWnd, do chng c k tha cc hm thnh vin t lp CWnd.
177

6.2. Thanh cng c v lp CToolbarCtrl


Thanh cng c lun c trn mi ng dng chng trnh, n l mt ca s cha cc nt lnh vai tr tng ng nh cc mc chn trn thc n. Thanh cng c c bao gi trong lp CToolBarCtrl ca MFC, tuy nhin c th s dng lp CToolBar thc hin. Cc bc to thanh cng c: Bc 1: To i tng CToolBarCtrl v gi lnh to Create() Bc 2: Thm cc nt lnh v nh bitmap cho nt lnh Bc 3: Thc hin nh x thng ip chn nt lnh tng ng

6.2.1. To thanh cng c


to mt thanh cng c, u tin phi to mt i tng kiu lp CToolBarCtrl v sau gi lnh Create() theo mu sau:
BOOL Create( DWORD st, RECT& rt, CWnd* pw, UINT ID );

Tham s st quy nh kiu thanh cng c, kiu ny phi gm gi tr WS_CHILD v c th kt vi cc WS_BORDER, WS_VISIBLE. Mt s kiu khc nh sau:
Gi tr TBSTYLE_TOOLTIPS TBSTYLE_WRAPABLE TBSTYLE_FLAT TBSTYLE_TRANSPARENT ngha Thanh cng c c tooltip C th xu ng hng n u qu di Nt l nh khng n i (W98/IE4) Thanh cng c trong su t (W98/IE4)

v mt s kiu iu khin chung c th gn vo ca s nh sau:


CCS_ADJUSTABLE CCS_BOTTOM CCS_LEFT CCS_NODIVIDER CCS_NOMOVEX CCS_NOMOVEY CCS_NOPARENTALIGN C th i u ch nh b i ng i dng N m N m v tr d i cng c a s bn tri

Khng c ng chia v i c a s Khng thay i kch th c chi u ngang Khng thay i kch th c chi u d c Khng t chuy n v tr trn/d i c a s

178

CCS_NORESIZE CCS_RIGHT CCS_TOP CCS_VERT

Kch th c v v tr c nh N m bn ph i N m pha trn

Cn theo chi u d c

Tham s rt thng c b qua, quy nh kch thc hnh ch nht cha thanh cng c trong trng hp kiu c gi tr CCS_NORESIZE. Mc nh thanh cng c nm pha trn ca s cha, t ng iu chnh kch thc v khng nn thay i cc kiu ny. Tham s pw quy nh ca s m cha thanh cng c v s hiu l ID. Sau khi to xong cha th dng thanh cng c bi cha c cc nt lnh v cc hnh nh t trn nt lnh.

6.2.2. Thm nt lnh vo thanh cng c


BOOL CToolBarCtrl::AddButton(int num, LPTBBUTTON bts);

Trong num l s nt lnh cn thm nm trong tham s bts, tham s bts cha danh sch cc nt lnh c kiu TBBUTTON khai bo theo mu sau:
typedef struct _TBBUTTON { int iBitmap; - ch s nh ca nt lnh int idCommand; - s hiu chc nng khi nh x thng ip BYTE fsState; BYTE fsStyle; - trng thi - kiu nt lnh - gi tr dnh cho ng dng

DWORD dwData;

int iString; - s hiu dng ch hin th cho nt lnh } TBBUTTON;

Gi tr thnh phn fsState c cc gi tr sau:


Gi tr TBSTATE_CHECKED TBSTATE_ELLIPSES TBSTATE_ENABLE TBSTATE_HIDDEN ngha Nt l nh b b m xu ng Hi n elp khi ch nt l nh b c t Nt l nh c th b m Nt l nh d ng n

179

TBSTATE_INDETERMINATE TBSTATE_MARKED TBSTATE_PRESSED TBSTATE_WRAP

Nt l nh d ng m Nt l nh c nh d u Nt l nh ang b b m xu ng Nt l nh ti p theo s xu ng hng

Gi tr thnh phn fsStyle c cc gi tr sau:


Gi tr TBSTYLE_AUTOSIZE TBSTYLE_BUTTON TBSTYLE_CHECK TBSTYLE_SEP ngha T ng i u ch nh kch th c so v i vn b n hi n th Nt l nh d ng chu n Nt l nh n i chm khi b m nh Nt l nh d ng phn cch, khi tham s idCommand ph i b ng 0.

6.2.3. Thm nh bitmap vo thanh cng c


int int CToolBarCtrl :: AddBitmap( int num, UINT ID ); CToolBarCtrl :: AddBitmap( int num, CBitmap* bmp );

Tham s num quy nh s nh bitmap cn thm, ID quy nh s hiu ti nguyn nh bitmap, bmp quy nh cc i tng nh bitmap np vo chng trnh. nh bitmap trn nt lnh thanh cng c c kch thc mc nh l 16x15 v c th to ra bi cng c to nh bitmap ca Visual C.

6.2.4. Thay i kch thc


Khi thanh cng c to ra kch thc s c iu chnh cho ph hp vi ca s cha hin ti, tuy nhin khi ca s cha thay i kch thc th thanh cng c khng t ng thay i theo do chng ta phi gi hm ny trong thng ip WM_SIZE theo mu sau:
void AutoSize( );

6.2.5. Mt s hm lin quan khc


Lnh t trng thi bm xung cho nt lnh:
BOOL PressButton( int id, BOOL press = TRUE );

Lnh n nt lnh:

180

BOOL

HideButton( int id, BOOL hide = TRUE );

Lnh bt/tt kch hot nt lnh:


BOOL EnableButton( int id, BOOL enable = TRUE );

Trong tham s id quy nh s hiu nt lnh cn thc hin, cc tham s th hai quy nh trng thi cho nt lnh.

V d 6.1
Lp trnh to mt thanh cng c c 5 nt lnh vi cc chc nng v cc hnh c bn (ch nht, trn, elp, ng thng, qut) ln ca s. X l thng ip bm chut tri v. Bc 1: To cc nh bitmap hin th cho cc nt lnh nh sau:

Bc 2: Ni dung chng trnh:


#include<afxwin.h> #include<afxcmn.h> #include"resource.h" UINT idCmd[5]={201,202,203,204,205}; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CDC mDC; CBitmap mBM; CBrush mBR; CToolBarCtrl tb; int idChon,mx,my; void InitToolbar(); public:

181

CMyWin(); afx_msg void OnLButtonDown(UINT nFlags,CPoint p); afx_msg void OnSize(UINT nType,int cx,int cy); afx_msg void OnPaint(); void OnCmd(UINT id); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_LBUTTONDOWN() ON_WM_SIZE() ON_WM_PAINT() ON_COMMAND_RANGE(idCmd[0],idCmd[4],OnCmd) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_BAR_CLASSES; InitCommonControlsEx(&ic); m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 01 - Chuong 06"); mx=GetSystemMetrics(SM_CXSCREEN); my=GetSystemMetrics(SM_CYSCREEN); CClientDC dc(this); mDC.CreateCompatibleDC(&dc); mBM.CreateCompatibleBitmap(&dc,mx,my); mDC.SelectObject(&mBM); mBR.CreateSolidBrush(WHITE_BRUSH); mDC.PatBlt(0,0,mx,my,PATCOPY); InitToolbar();

182

idChon=-1; } void CMyWin::InitToolbar() { RECT rt; rt.left=rt.top=rt.right=rt.bottom=0; tb.Create(WS_CHILD|WS_BORDER|WS_VISIBLE,rt,this,1); TBBUTTON b[5]; for (int i=0;i<5;i++) { b[i].fsStyle = TBSTYLE_BUTTON; b[i].fsState = TBSTATE_ENABLED; b[i].iBitmap=i; b[i].idCommand=idCmd[i]; b[i].dwData = 0; b[i].iString = 0; } tb.AddButtons(5,b); tb.AddBitmap(5,IDB_BITMAP1); } void CMyWin::OnLButtonDown(UINT nFlags,CPoint p) { CBrush b; CPen p1; p1.CreatePen(PS_SOLID,1,RGB(0,0,255)); b.CreateHatchBrush(HS_CROSS,RGB(255,0,255)); mDC.SelectObject(&p1); mDC.SelectObject(&b); switch (idChon) { case 0: mDC.MoveTo(0,0); mDC.LineTo(p); break; case 1: mDC.Rectangle(p.x,p.y,p.x+100,p.y+50); break; case 2:

183

mDC.Arc(p.x,p.y,p.x+100,p.y+70,p.x,p.y,p.x,p.y); break; case 3: mDC.Ellipse(p.x,p.y,p.x+70,p.y+120); break; case 4: mDC.Pie(p.x,p.y,p.x+100,p.y+150,p.x,p.y,p.x+150,p.y); break; } p1.DeleteObject(); b.DeleteObject(); InvalidateRect(NULL); } void CMyWin::OnCmd(UINT id) { this->idChon = id - idCmd[0]; } void CMyWin::OnSize(UINT nType,int cx,int cy) { tb.AutoSize(); } void CMyWin::OnPaint() { RECT rt; CPaintDC dc(this); tb.GetWindowRect(&rt); dc.BitBlt(0,rt.bottom-rt.top,mx,my,&mDC,0,0,SRCCOPY); }

Trong chng trnh cc s hiu ca nt lnh c lu trong mng idCmd vi 5 phn t, vic to thanh cng c v np cc nt lnh c thc hin trong hm InitToolbar(). Thao tc v c thc hin trn ca s o sau chp vo ca s tht qua hm x l thng ip WM_PAINT. Kt qu chng trnh sau khi chn mt s chc nng v nh sau:

184

6.2.6. Thm Tooltip vo nt lnh, lp CTooltipCtrl


Chng ta thy trn cc ng dng ca Windows cc thanh cng c c cc mu vn bn nh xut hin khi a chut qua trn ta gi l Tooltip. thm Tooltip vo thanh cng c ta thc hin cc phn nh sau: Bc 1: Khi to thanh cng c bng lnh Create ta phi thm gi tr kiu l TBSTYLE_TOOLTIPS. Bc 2: Trong hm ca s nh x x l thng ip WM_NOTIFY bng macro sau:
ON_NOTIFY_EX( TTN_GETDISPINFO , 0 , OnTooltip)

Hm x l thng ip tng ng l OnTooltip c khai bo theo mu sau:


afx_msg BOOL OnTooltip (UINT id,NMHDR *hdr, LRESULT *rs);

Trong id l s hiu ca iu khin c tooltip, hai tham s rs v id khng c s dng trong hm x l thng ip ny. Cc thng tin lin quan n thng ip c lu trong tham s hdr c kiu MNHDR, chng ta s dng tham s ny xc nh vn bn cho tooltip. Khi x l chng ta phi p con tr hdr thnh con tr kiu NMTTDISPINFO, c khai bo nh sau:

185

typedef

struct

tagNMTTDISPINFO {

NMHDR LPTSTR char

hdr; lpszText; - vn bn hin th cho tooltip

szText[80]; - vng nh lu vn bn tooltip - s hiu chng trnh

HINSTANCE hinst; UINT uFlags;

} NMTTDISPINFO, FAR *LPNMTTDISPINFO;

Thnh phn u hdr c kiu cu trc MNHDR c khai bo nh sau:


typedef struct tagNMHDR { HWND hwndFrom; - s hiu ca s cha iu khin UINT idFrom; - s hiu iu khin UINT code; - m thng bo } NMHDR;

Trong hm OnTooltip x l thng ip WM_NOTIFY chng ta a vo vn bn tooltip hin th cho iu khin nt lnh trn thanh cng c qua tham s hdr, da vo gi tr idFrom ca hdr bit s hiu nt lnh.

V d 6.2
Lp trnh to mt thanh cng c nh v d trc v c thm tooltip hin th cho tng nt lnh. Cho php n hin toolbar bng thc n. Ti nguyn nh bitmap cho cc nt lnh c to nh v d trc v ni dung chng trnh nh sau:
#include<afxwin.h> #include<afxcmn.h> #include"resource.h" UINT idCmd[5]={201,202,203,204,205}; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd

186

{ private: CMenu mn; CToolBarCtrl tb; public: CMyWin(); afx_msg BOOL OnTTip(UINT id,NMHDR *hdr,LRESULT *rs); void OnCmd(UINT id); void InitToolbar(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_NOTIFY_EX(TTN_GETDISPINFO,0,OnTTip) ON_COMMAND_RANGE(ID_SHOW,ID_HIDE,OnCmd) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_BAR_CLASSES; InitCommonControlsEx(&ic); m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 02 - Chuong 06"); mn.CreateMenu(); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_SHOW,"Show toolbar"); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,ID_HIDE,"Hide toolbar"); SetMenu(&mn); InitToolbar(); }

187

void CMyWin::InitToolbar() { RECT rt; rt.left=rt.top=rt.right=rt.bottom=0; tb.Create(WS_CHILD|WS_BORDER|WS_VISIBLE|TBSTYLE_TOOLTIPS,rt,this,1); TBBUTTON b[5]; for (int i=0;i<5;i++) { b[i].fsStyle = TBSTYLE_BUTTON; b[i].fsState = TBSTATE_ENABLED; b[i].iBitmap=i; b[i].idCommand=idCmd[i]; b[i].dwData = 0; b[i].iString = 0; } tb.AddButtons(5,b); tb.AddBitmap(5,IDB_BITMAP1); } afx_msg BOOL CMyWin::OnTTip(UINT id,NMHDR *hdr,LRESULT *rs) { switch (hdr->idFrom-idCmd[0]) { case 0: ((NMTTDISPINFO *)hdr)->lpszText = "Ve duong thang"; break; case 1: ((NMTTDISPINFO *)hdr)->lpszText = "Ve hinh chu nhat"; break; case 2: ((NMTTDISPINFO *)hdr)->lpszText = "Ve hinh tron"; break; case 3: ((NMTTDISPINFO *)hdr)->lpszText = "Ve hinh elip"; break; case 4: ((NMTTDISPINFO *)hdr)->lpszText = "Ve hinh quat"; break; } return TRUE; } void CMyWin::OnCmd(UINT id)

188

{ if (id==ID_SHOW) { tb.ShowWindow(SW_RESTORE); } else { tb.ShowWindow(SW_HIDE); } }

Kt qu chng trnh l:

Ngoi ra chng ta c th dng lp CToolTipCtrl trong th vin MFC to v s dng tooltip cho cc iu khin khc thanh cng c trn ca s cng nh hp thoi. Cc bc thc hin to v t tooltip s dng lp CToolTipCtrl nh sau: Bc 1: To mt i tng CToolTipCtrl. Bc 2: Gi hm to Create() theo mu sau:
BOOL Create( CWnd* pParentWnd, DWORD dwStyle = 0 );

Bc 3: Thm cc iu khin vo thc hin tooltip bng cch gi hm:


BOOL id); AddTool( CWnd* wnd, LPCTSTR txt, LPCRECT rt, UINT

Bc 4: Kch hot tooltip:


void Activate( BOOL bActivate );

189

Hm to Create() c tham s pParentWnd quy nh ca s cha i tng tooltip, dwStyle quy nh kiu ca s tooltip bao gm cc gi tr TTS_ALWAYSTIP, WS_POPUP, WS_EX_TOOLWINDOW. Hm thm AddTool() c tham s wnd quy nh ca s cha iu khin cn thm tooltip, txt l vn bn hin th cho tooltip, rt quy nh vng ch nht gii hn tc ng chut cho hin tooltip v id l s hiu iu khin cn thm. Hm Activate() bt hoc tt kch hot ca tooltip, nu tham s bActivate l TRUE th bt v ngc li.

6.3. iu khin Up-Down v Spin


Mt iu khin cho php ngi dng nhp d liu dng s bng cch bm chut vo mi tn ln xung tng gim gi tr, gi l iu khin spin. iu khin ny c dng nh thanh cun nhng ch c hai mi tn, khng c thanh trt bar v con chy. S dng iu khin ny theo hai dng, mt l di dng ging nh mt thanh cun scrollbar, hai l kt hp vi mt i tng khc nh editbox hin gi tr ca iu khin. Khi s dng kt hp th iu khin c kt hp gi l buddy window. iu khin spin c bao gi bi lp CSpinButtonCtrl, do trc ht bn phi to mt i tng t lp ny, v d:
CSpinButtonCtrl spin;

6.3.1. To iu khin spin


BOOL Create( DWORD st, RECT& rt, CWnd* pw, UINT nID );

Tham s st quy nh kiu ca spin, thng thng gm cc gi tr WS_CHILD, WS_VISIBLE, WS_BORDER. Tham s rt quy nh kch thc v v tr ca spin. Ca s m cha iu khin l pw v nID l s hiu ca spin. Hm to iu khin spin trn (Create()) s tr v gi tr TRUE nu thnh cng, ngc li tr v FALSE nu b li.

190

6.3.2. X l thng ip ca spin


Khi ngi dng tc ng ln spin s pht sinh thng ip WM_VSCROLL gi ti ca s m. Bn phi nh x x l thng ip ny thc hin cc x l tng ng, nh ly gi tr ca spin hin ln ca s chng hn. Hm nh x x l thng ip ny c mu khai bo nh sau:
void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );

Trong : + nSBCode cha kiu ca spin khi hat ng, bao gm cc gi tr sau:
Gi tr UDS_ALIGNLEFT UDS_ALIGNRIGHT UDS_ARROWKEYS UDS_AUTOBUDDY UDS_HORZ UDS_NOTHOUSANDS UDS_SETBUDDYINT ngha Spin n m bn tri i u khi n k t h p (buddy) Spin n m bn ph i buddy Cho php s d ng phm mi tn C a s buddy n m sau i u khi n spin Spin chi u ngang (m c nh l chi u d c) Khng s d ng d u ngn cch 3 ch s T ng hi n th gi tr spin ln c a s buddy

Tuy nhin tham s nSBCode ny thng c t t ng, do vy bn khng phi chn gi tr cho tham s ny. + nPos cha gi tr ca spin ng vi thng ip gi ti, + pScrollBar l con tr ti thanh cun tng ng, gi tr ny c ngha khi c nhiu spin trn ca s v chng ta phi da vo tham s ny bit gi tr ca spin no.

6.3.3. Mt s hm khc ca spin


- t hoc ly min gii hn ca spin
int int CSpinButtonCtrl :: SetRange( int min, int max ); CSpinButtonCtrl :: GetRange( int &min, int &max );

- t hoc ly gi tr ca spin
int int CSpinButtonCtrl :: SetPos( int pos ); CSpinButtonCtrl :: GetPos(); 191

Trong min v max l gi tr nh nht v ln nht ca spin, gi tr pos trong hm SetPos() l gi tr cn t cho spin, hm GetPos() tr v gi tr ca spin.

V d 6.3
Lp trnh to mt spin theo kiu c lp trn ca s v x l thng ip WM_VSCROLL hin th gi tr ca spin ln ca s. Ni dung chng trnh nh sau:
#include<afxwin.h> #include<afxcmn.h> #define IDD_SPIN 174 class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CSpinButtonCtrl spin; public: CMyWin(); void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar *pSB); void InitControl(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_VSCROLL() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin()

192

{ Create(NULL,"Vi du 03 - Chuong 06"); InitControl(); } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_UPDOWN_CLASS; InitCommonControlsEx(&ic); RECT rt; rt.left = 150; rt.top = 50; rt.right = rt.bottom = rt.top+50; spin.Create(WS_VISIBLE|WS_CHILD|WS_BORDER,rt,this,IDD_SPIN); spin.SetRange(0,99); spin.SetPos(50); } void CMyWin::OnVScroll(UINT nSBCode,UINT nPos,CScrollBar *pSB) { if (pSB!=(CScrollBar*)&spin) return; CDC *dc=GetDC(); char s[20]; sprintf(s,"%d ",LOWORD(spin.GetPos())); dc->TextOut(100,60,s,strlen(s)); }

Trong hm x l thng ip WM_VSCROLL c s dng macro LOWORD xc nh gi tr 2 byte thp ca gi tr tr v t hm GetPos() trn spin. Kt qu ca chng trnh l:

193

6.3.4. To spin kt hp vi editbox


Nh chng ta thy trong v d trn gi tr ca spin c hin th ln ca s trong hm nh x thng ip OnVScroll(), gi tr ny t ng cp nht khi tc ng ln spin ta s dng kt hp vi editbox. Trn ca s chng ta phi to hai iu khin editbox v spin, c th s dng lp CEdit to mt iu khin editbox trn ca s bng lnh Create() khai bo theo mu sau:
BOOL CEdit :: Create( DWORD st, RECT& rt, CWnd* pw, UINT nID );

Tham s st quy nh kiu editbox, rt quy nh hnh ch nht ng vi kch thc v v tr editbox, pw l ca s cha v nID l s hiu ca editbox. iu khin spin to ra phi c thm gi tr kiu UDS_SETBUDDYINT v c th cc gi tr khc nh bng trn. Sau t kt hp spin vi editbox ta s dng hm thnh vin ca lp CSpinButtonCtrl nh sau:
CWnd* SetBuddy( CWnd* pWndBuddy );

Tham s pWndBuddy quy nh ca s iu khin s c kt hp, y s l iu khin editbox. Hm tr v ca s kt hp trc . Sau khi kt hp editbox vi spin th gi tr ca spin s c cp nht t ng khi c tc ng thay i ln spin.

V d 6.4
Lp trnh to spin kt hp vi editbox hin gi tr ln ca s. Ni dung chng trnh s l:
#include<afxwin.h> #include<afxcmn.h> #define #define IDD_SPIN 174 IDD_EDIT 142

class CMyApp : public CWinApp { public: BOOL InitInstance(); };

194

class CMyWin : public CFrameWnd { private: CSpinButtonCtrl spin; CEdit edit; public: CMyWin(); void InitControl(); }; CMyApp theApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 04 - Chuong 06"); InitControl(); } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_UPDOWN_CLASS; InitCommonControlsEx(&ic); RECT rt; rt.left=100; rt.top=50; rt.right=rt.left+50; rt.bottom=rt.top+30; edit.Create(WS_VISIBLE|WS_CHILD|WS_BORDER,rt,this,IDD_EDIT); rt.left = 10; rt.top = 10; rt.right = rt.bottom = rt.top+40; spin.Create(WS_VISIBLE|WS_CHILD|WS_BORDER|UDS_SETBUDDYINT| UDS_ALIGNRIGHT,rt,this,IDD_SPIN); spin.SetBuddy(&edit); spin.SetRange(0,99); spin.SetPos(50); }

195

Kt qu chng trnh s l:

6.4. iu khin Slider v Progress Bar


Mt iu khin khc tng t thanh cun gi l thanh trt (trackbar). iu khin ny c mt thanh trt c chia theo thanh n v t gi tr min n gi tr max, trn c mt con chy dch chuyn theo tng n v . iu khin slider c bao gi bi lp CSliderCtrl.

6.4.1. To iu khin Slider


BOOL CSliderCtrl :: Create(DWORD st,RECT& rt,CWnd* pw,UINT nID);

Trong tham s st quy nh kiu iu khin slider thng gm cc gi tr WS_VISIBLE, WS_CHILD, WS_BORDER. Ngoi ra bn nn t thm gi tr TBS_AUTOTICKS vo tham s ny iu khin c hin th thang chia, mt s gi tr khc trong bng sau. Kch thc v v tr c quy nh bi tham s rt, pw l ca s m cha iu khin cn to v nID l s hiu iu khin.
Ki u i u khi n slider TBS_AUTOTICKS TBS_TOOLTIPS TBS_NOTICKS TBS_HORZ TBS_VERT TBS_BOTTOM TBS_TOP ngha T ng hi n th thang chia C tooltip h ng d n Khng c thang chia Slider n m ngang Slider n m d c Thang chia n m pha d i slider Thang chia n m pha trn

196

TBS_LEFT TBS_RIGHT TBS_BOTH

Thang chia n m pha tri Thang chia n m pha ph i Thang chia n m c hai pha

6.4.2. X l thng ip Slider


Khi ngi dng tc ng ln iu khin slider my s pht sinh thng ip WM_HSCROLL gi ti ca s cha n, bn phi nh x x l thng ip ny bng hm OnHScroll() khai bo theo mu sau:
void CSliderCtrl::OnHScroll( UINT nSB, UINT nPos, CScrollBar* pSB );

Tham s nSB cha trng thi ca slider, bao gm cc gi tr trong bng sau. nPos cha gi tr ca con chy trn slider v pSB con tr ti iu khin c thng ip tng ng. Nu pSB l NULL th iu khin c thng ip chnh l thanh cun trn ca s, ngc li bn dng bin tr ny so snh vi iu khin to ra x l yu cu.
Tr ng thi slider TB_BOTTOM TB_ENDTRACK TB_LINEDOWN TB_LINEUP TB_PAGEDOWN TB_PAGEUP TB_THUMBPOSITION TB_THUMBTRACK TB_TOP ngha B m phm end, chuy n v gi tr min Sau khi nh phm end Nh n phm mi tn ph i ho c xu ng Nh n phm mi tn ln ho c tri Nh n phm pagedown Nh n phm pageup Chuy n con tr t b ng chu t Ko th con tr t b ng chu t Phm home c nh n, chuy n t i gi tr max

6.4.3. Cc hm khc ca lp Slider


- Min gii hn ca slider
void void SetRange( int nMin, int nMax, BOOL bRedraw = FALSE ); GetRange( int& nMin, int& nMax ) const;

- Gi tr con trt trn slider


void SetPos( int nPos );

197

int

GetPos( ) const;

Tham s nMin v nMax quy nh gi tr nh nht v ln nht trn thanh trt, nPos l gi tr hin ti cn t cho thanh trt. Hm GetPos() tr v gi tr hin ti, tng t hm GetRange() tr v gi tr gii hn thanh trt.

V d 6.5
Lp trnh to thanh trt trn ca s v x l thng ip WM_HSCROLL hin gi tr con trt ln ca s. Ni dung chng trnh l:
#include<afxwin.h> #include<afxcmn.h> #define IDD_SLIDER 174 class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CSliderCtrl slider; public: CMyWin(); void InitControl(); afx_msg void OnHScroll(UINT nSB, UINT nPos, CScrollBar* pSB); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_HSCROLL() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin()

198

{ Create(NULL,"Vi du 05 - Chuong 06"); InitControl(); } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_UPDOWN_CLASS; InitCommonControlsEx(&ic); RECT rt; rt.left=50; rt.top=50; rt.right=rt.left+250; rt.bottom=rt.top+30; slider.Create(WS_VISIBLE|WS_CHILD|WS_BORDER|TBS_AUTOTICKS, rt,this,IDD_SLIDER); slider.SetRange(0,50); slider.SetPos(15); } void CMyWin::OnHScroll(UINT nSB, UINT nPos, CScrollBar* pSB) { if (pSB!=(CScrollBar*)&slider) return; CDC *dc=GetDC(); char s[20]; sprintf(s,"%d ",LOWORD(slider.GetPos())); dc->TextOut(150,30,s,strlen(s)); }

Chng trnh ny thc hin ng k lp iu khin m rng s dng tham s kiu ICC_UPDOWN_CLASSES. Lnh to iu khin slider c kiu gm cc gi tr thng thng WS_VISIBLE, WS_CHILD, WS_BORDER v c thm kiu TBS_AUTOTICKS hin thang chia n v. Kt qu chy chng trnh l:

199

6.4.4. iu khin Progress bar


iu khin Progress bar l mt thanh tin trnh, n thng th hin cho mt tin trnh cng vic thc hin trn my tnh. Thanh tin trnh c bao gi bi lp CProgressCtrl. - To iu khin thanh tin trnh
BOOL nID ); Create( DWORD st, RECT& rt, CWnd* pw, UINT

Trong tham s st quy nh kiu ca thanh tin trnh thng l WS_CHILD, WS_VISIBLE, WS_BORDER. Kch thc v v tr c quy nh bi tham s rt vi kiu RECT, pw l ca s m cha iu khin v nID l s hiu ca thanh tin trnh. Ngoi ra bn c th to thanh tin trnh c kiu ng v dng trn bng cch thm cc gi tr kiu sau: PBS_SMOOTH v PBS_VERTICAL. Tham s rt quy nh kch thc v v tr iu khin thng thng chng ta s dng hm to lp CRect to trc tip theo cch sau:
CRect( left , top , right , bottom )

- t v ly min gii hn thanh tin trnh


void void void SetRange( short nLower, short nUpper ); SetRange32( int nLower, int nUpper ); GetRange( int& nLower, int& nUpper );

Tham s nLower l s gii hn di (nh nht), nUpper l s gii hn trn (ln nht). - t v ly gi tr hin ti ca thanh tin trnh
int int SetPos( int nPos ); GetPos( );

- t bc nhy v thc hin bc nhy


int int SetStep( int nStep ); StepIt( );

200

Tham s nStep quy nh ln bc nhy ca thanh tin trnh. Hm StepIt() thc hin mt bc nhy, tng gi tr hin ti ca thanh tin trnh thm mt lng ng bc nhy. Khi thc hin bc nhy thanh tin trnh s c cp nht bi dy mu th hin tng dn. Nu thc hin bc nhy vt qu gi tr gii hn ln nht th n s t ng chuyn v u.

V d 6.6
Lp trnh to mt thanh tin trnh trn ca s v mt nt lnh cho php bm chut thc hin bc nhy, khi ht mt tin trnh th t ng ng ca s.
#include<afxwin.h> #include<afxcmn.h> #define IDD_PRG 174 #define IDD_PROGRESS 142 class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CProgressCtrl prg; CButton bt; public: CMyWin(); void InitControl(); void OnProgress(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND( IDD_PROGRESS , OnProgress ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow();

201

return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 06 - Chuong 06"); InitControl(); } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_PROGRESS_CLASS; InitCommonControlsEx(&ic); prg.Create(WS_VISIBLE|WS_CHILD|WS_BORDER, CRect(50,50,300,80),this,IDD_PRG); prg.SetRange(0,100); prg.SetStep(10); prg.SetPos(0); bt.Create("Progress",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON ,CRect(130,100,210,130),this,IDD_PROGRESS); } void CMyWin::OnProgress() { int mi,ma; prg.StepIt(); prg.GetRange(mi,ma); if (prg.GetPos()>=ma) DestroyWindow(); }

Chng trnh to hai iu khin thanh tin trnh s dng lp CProgressCtrl v nt lnh s dng lp CButton. nh x x l thng ip bm nt lnh thc hin bc nhy cho thanh tin trnh. Lnh to nt bm t lp CButton nh sau:
BOOL CButton::Create( LPCTSTR ct, DWORD st, RECT& rt, CWnd* pw, UINT nID );

Trong ct l tiu hin th cho nt bm, st l kiu nt bm gm c WS_CHILD, WS_VISIBLE v BS_PUSHBUTTON, rt l tham s quy nh kiu v v tr, pw l ca s m v nID l s hiu ca s.

202

Kt qu chng trnh l:

6.5. Thanh trng thi v lp CStatusBar


Thanh trng thi (status bar) thng c mi ca s ng dng n hin th cc tnh trng lm vic ca ng dng v c gn vo di ca s ng dng. Thanh trng thi c bao gi bi lp CStatusBarCtrl, tuy nhin chng ta c th s dng lp CStatusBar thay th.

6.5.1. To thanh trng thi


Trc ht bn phi to i tng t lp CStatusBarCtrl v thc hin hm to iu khin ny theo mu sau:
BOOL Create( DWORD st, RECT& rt, CWnd* pw, UINT nID );

Tham s st quy nh kiu thanh trng thi thng gm WS_CHILD, WS_VISIBLE, WS_BORDER. Ngoi ra cn c cc gi tr c th dng cho kiu ny bng sau. Tham s rt s b qua, nu t kiu l CCS_NORESIZE th v tr v kch thc c quy nh trong tham s rt. Ca s m cha thanh trng thi quy nh bi pw v nID l s hiu thanh trng thi.
Ki u thanh tr ng thi CCS_BOTTOM CCS_NODIVIDER CCS_NOHILITE CCS_NOMOVEY ngha Thanh tr ng thi n m pha d i c a s Khng c ng chia gi a thanh tr ng thi v i c a s Khng sng ln khi n m pha trn c a s Khng thay i chi u d c

203

CCS_NOPARENTALIGN CCS_NORESIZE CCS_TOP

Khng t ng cn ch nh theo c a s Khng thay i kch th c N m pha trn c a s

6.5.2. t cc phn trn thanh trng thi


Thng thng thanh trng thi hin th nhiu thng tin v trng thi ca chng trnh, mi thng tin c hin th trong mt gi l part. Sau khi to thanh trng thi s t ng chia lm hai , tuy nhin c th t li theo hm sau:
BOOL SetParts( int nParts, int* pWidths );

Trong tham s nParts quy nh s c chia trn thanh trng thi v pWidths l mng c s phn t bng s c chia, mi phn t cha ta y quy nh kch thc rng ca tng ng.

6.5.3. t vn bn hin th cho cc


hin vn bn vo mt ca thanh trng thi s dng hm sau:
BOOL SetText( LPCTSTR lpszText, int nPane, int nType );

Trong lpszText l vn bn cn hin th, nPane l th t v nType quy nh kiu khng s dng v t tham s ny l 0. Th t s bt u t 0. Cc bc thc hin to v s dng thanh trng thi: Bc 1: To thanh trng thi cho ca s chng trnh. Bc 2: t s chia trn thanh trng thi. Bc 3: t hin th vn bn vo tng . Bc 4: Cp nht vn bn hin th khi c s thay i trong chng trnh.

V d 6.7
Lp trnh to thanh trng thi trn ca s v chia lm 3 hin th trng thi ba phm CapsLock, NumLock, Insert. X l thng ip WM_KEYDOWN kim tra trng thi phm v hin th li trng thi . Ni dung chng trnh s nh sau:
204

#include<afxwin.h> #include<afxcmn.h> #define IDD_STATUS 142 class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CStatusBarCtrl st; int ins; public: CMyWin(); void InitControl(); afx_msg void OnKeyDown(UINT nChar,UINT nRep,UINT nFlags); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_WM_KEYDOWN() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 07 - Chuong 06",WS_OVERLAPPEDWINDOW, CRect(100,100,500,300)); InitControl(); ins=1; } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_BAR_CLASSES;

205

InitCommonControlsEx(&ic); int y[3]={70,150,250}; st.Create(WS_VISIBLE|WS_CHILD|CCS_BOTTOM|SBARS_SIZEGRIP, CRect(0,0,0,0),this,IDD_STATUS); st.SetParts(3,y); OnKeyDown(0,0,0); } void CMyWin::OnKeyDown(UINT nChar,UINT nRep,UINT nFlags) { SHORT k = GetKeyState(VK_CAPITAL); if (k&1) st.SetText("CAP : ON",0,0); else st.SetText("CAP : OFF",0,0); k = GetKeyState(VK_NUMLOCK); if (k&1) st.SetText("NUM : ON",1,0); else st.SetText("NUM : OFF",1,0); if (nChar==VK_INSERT) ins=-ins; if (ins>0) st.SetText("INS : ON",2,0); else st.SetText("INS : OFF",2,0); }

Chng trnh trn to mt ca s c kch thc c quy nh bi hm to CRect(100,100,500,300) trong lnh Create(). Trong hm InitControl() ca lp CMyWin thc hin khi to lp ICC_BAR_CLASSES cho vic to thanh trng thi. Thanh trng thi to ra c chia lm 3 v hin th trng thi 3 phm theo yu cu. Hm OnKeyDown() thc hin ly trng thi cc phm v hin vo tng trng thi, s dng hm ly trng thi phm l GetKeyState() c mu nh sau:
SHORT GetKeyState( int nVirtKey );

Hm trn ca th vin API v tham s nVirtKey quy nh phm cn kim tra nh VK_INSERT, VK_CAPITAL, VK_NUMLOCK,... hm tr v gi tr kiu SHORT, trong bt thp nht cha trng thi bt, tt ca phm kim tra. Vi phm Insert chng ta khai bo bin trng thi ins tng ng, khi u t ins=1, sau mi ln nhn phm ny th s o du bng lnh ins=-ins. Da vo gi tr ins l m hay dng s hin th trng thi tt hay bt.

206

Kt qu chng trnh l:

6.6. iu khin Tab


iu khin tab l mt ca s c nhiu th hin cc thng tin khc nhau vi nhng giao tc khc nhau, mi th gi l item. Ti mt thi im ch mt th c chn v lm vic. iu khin ny c bao gi bi lp CTabCtrl.

6.6.1. To iu khin Tab


Trc ht bn phi to mt i tng t lp CTabCtrl, sau thc hin lnh to bng hm khai bo theo mu sau:
BOOL Create( DWORD st, RECT& rt, CWnd* pw, UINT nID );

Tham s st quy nh kiu tab gm cc gi tr WS_CHILD, WS_VISIBLE v cc gi tr bng sau:


Gi tr TCS_BUTTONS TCS_FIXEDWIDTH TCS_MULTILINE TCS_TOOLTIPS TCS_SINGLELINE ngha S d ng nt b m, khng s d ng th T t c cc th tab c kch th c nh nhau Th tab c nhi u dng C hi n th tooltip Th tab c m t dng

Tham s rt quy nh v tr v kch thc ca tab, ca s m cha tab l pw v nID l s hiu iu khin tab.

207

6.6.2. Thit lp cc th Tab


Sau khi to iu khin Tab bn phi thit lp cc th tab, thc hin chn thm cc th tab bng mt trong cc mu hm sau:
BOOL BOOL BOOL InsertItem( int idx, TCITEM* pItem ); InsertItem( int idx, LPCTSTR sItem ); InsertItem( int idx, LPCTSTR sItem, int nImage );

BOOL InsertItem( UINT nMask, int nItem, LPCTSTR sItem, int nImage, LPARAM lParam );

Trong tham s idx quy nh s th t ca th tab c thm vo, th tab bt u t s 0. pItem c kiu TCITEM quy nh cc tham s ca th tab cn thm, cu trc TCITEM c khai bo nh sau:
typedefstruct tagTCITEM { UINT DWORD DWORD mask; dwState; dwStateMask;

LPSTR pszText; int int cchTextMax; iImage; lParam;

LPARAM } TCITEM;

Thnh phn mask quy nh th tab s hin th vn bn, hnh nh hay lu trong phn lParam, n bao gm mt trong cc gi tr sau:
Gi tr TCIF_IMAGE TCIF_PARAM TCIF_STATE TCIF_TEXT ngha Thnh ph n iImage ch a d li u c a th tab lParam ch a d li u dwState ch a d li u pszText ch a d li u

208

Thnh phn mask c th thm TCIF_RTLREADING quy nh vn bn hin th trn th tab t phi sang tri. Thnh phn iImage cha s th t hnh nh hin th trn th tab, cc nh ny c lu trong i tng CImageList v c kt hp vi iu khin tab. Tuy nhin thng thng chng ta s dng th tab dng vn bn, do bn ch cn s dng mu 2 trong cc mu trn:
BOOL InsertItem( int idx, LPCTSTR sItem );

Tham s sItem l vn bn cn hin th cho th tab c thm.

6.6.3. Cc hm khc ca lp CTabCtrl


- Th tab hin thi ang chn t th tab hin thi hoc xc nh th tab ang chn ta s dng mu hm sau:
int int SetCurSel( int nItem ); GetCurSel( ) const;

Trong nItem l s th t th tab cn t, hm GetCurSel() tr v s th t th tab hin thi ang chn. - Thng tin v th tab xc nh thng tin v th tab ta s dng hm GetItem(), hoc t thng tin cho th tab s dng hm SetItem(), hai hm c khai bo theo mu sau:
BOOL BOOL SetItem( int nItem, TCITEM* pTabCtrlItem ); GetItem( int nItem, TCITEM* pTabCtrlItem ) const;

Trong nItem l s th t th tab, pTabCtrlItem cha thng tin v th tab c cu trc TCITEM nh m t phn trc. - Nu mun iu chnh li kch thc ca tab ta s dng hm sau:
void AdjustRect( BOOL bLarger, LPRECT lpRect );

Trong bLarger quy nh t hay ly kch thc ca tab, nu bng 0 th lnh ny tr v cu trc lpRect cha kch thc, ngc li bng 1 s t tab theo kch thc trong tham s lpRect.
209

6.6.4. X l thng ip lin quan n Tab


Khi ngi dng tc ng ln iu khin Tab, thng ip WM_NOTIFY c sinh ra v gi n ca s cha n. iu khin tab sinh ra hai m thng ip thay i la chn th tab gm TCN_SELCHANGE v TCN_SELCHANGING, tng ng vi hai thi im chn xong hoc ang chn th tab. nh x x l thng ip cho iu khin tab bn s dng macro theo mu sau:
ON_NOTIFY ( m-thng-ip , s-hiu , tn-hm )

Trong m thng ip l hai gi tr nh trn (TCN_SELCHANGE hoc TCN_SELCHANGING), tip theo l s hiu ca iu khin tab tng ng khi to ra v tn hm nh x x l thng ip. Mu khai bo hm nh x x l thng ip WM_NOTIFY nh sau:
afx_msg void tn-hm ( NMHDR *hdr, LRESULT *rs);

Vi m thng ip l TCN_SELCHANGE th tham s rs khng s dng, vi m l TCN_SELCHANGING th chng ta t gi tr rs l 0 nu ng thay i la chn t ngi dng, ngc li t khc 0.

V d 6.8
Lp trnh to mt iu khin tab trn ca s, x l thng ip TCN_SELCHANGING hi ngi s dng c ng thay i la chn th tab hay khng. Ni dung chng trnh l:
#include<afxwin.h> #include<afxcmn.h> #define IDD_TAB 174 class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: CTabCtrl tab;

210

public: CMyWin(); void InitControl(); afx_msg void OnSelChanging(NMHDR *hdr,LRESULT *rs); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_NOTIFY( TCN_SELCHANGING, IDD_TAB, OnSelChanging ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 08 - Chuong 06",WS_OVERLAPPEDWINDOW, CRect(100,100,700,500)); InitControl(); } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_TAB_CLASSES; InitCommonControlsEx(&ic); RECT rt; GetClientRect(&rt); tab.Create(WS_VISIBLE|WS_CHILD,rt,this,IDD_TAB); tab.InsertItem(0,"One"); tab.InsertItem(1,"Two"); tab.InsertItem(2,"Three"); } void CMyWin::OnSelChanging(NMHDR *hdr,LRESULT *rs) { if (MessageBox("Dong y khong?","Hoi ban",MB_YESNO)==IDYES) *rs=0; else *rs=1; }

211

Kt qu thc hin khi bn chn mt th tab s l:

6.7. iu khin Tree View


Tree view l mt iu khin cho php hin th thng tin ln ca s di dng cy, v d nh ca s cy th mc ca Window Explore. iu khin ny c rt nhiu tham s la chn khi to v lm vic, tuy nhin chng ta ch tham kho mt s phn c bn. Lp CTreeCtrl s lm vic trn iu khin ny, tuy nhin chng ta c th dng lp CTreeView s a dng hn.

6.7.1. To iu khin Tree View


Trc ht bn phi to mt i tng t lp CTreeCtrl v thc hin hm Create() theo mu sau:
BOOL Create( DWORD st, RECT& rt, CWnd* pw, UINT nID );

Trong st quy nh kiu ca tree view bao gm WS_CHILD, WS_VISIBLE v c thm cc gi tr sau:
Gi tr TVS_EDITLABELS TVS_HASLINES TVS_LINESATROOT TVS_HASBUTTONS ngha Ng i dng c th thay i nhn trn tree view C ng n i gi a cc nhnh trn tree view C ng n i gi a nt g c v i cc nhnh C nt b m m r ng (+) hay thu h p (-) cc nhnh

Tham s rt quy nh kch thc v v tr ca iu khin, pw l ca s m cha iu khin v nID l s hiu cho iu khin to ra.

212

6.7.2. Thm cc nt vo iu khin Tree View


Sau khi to xong iu khin tree view th n cha c cc mc (cy rng), bn phi thm cc mc bng hm sau:
HTREEITEM InsertItem( TVINSERTSTRUCT *item );

Hoc cc hm np chng tng t nhng vi cc tham s c quy nh khc nhau nh sau:


HTREEITEM InsertItem( UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEM hInsertAfter ); HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST ); HTREEITEM InsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);

Tham s item ca mu mt l mt cu trc TVINSERTSTRUCT lu cc thng tin ca mc s c thm vo cy, cu trc c khai bo nh sau:
typedefstruct tagTVINSERTSTRUCT { HTREEITEM HTREEITEM union { hParent; hInsertAfter; item;

TVITEMEX TVITEM

item;

} } TVINSERTSTRUCT;

213

Cn cc mu hm sau c tham s tng t nh cc thnh phn ca cu trc trn. Trong hParent l nh danh ca mc m, nu mc cn thm l gc th thnh phn ny phi c gi tr l TVI_ROOT. Gi tr hInsertAfter quy nh mc thm vo s nm sau mc no trong cy (tree view), hoc c th mt trong cc gi tr sau:
Gi tr TVI_FIRST TVI_LAST TVI_SORT ngha M c thm vo s n m u tin M c thm vo n m cu i cng Cc m c thm vo s c s p x p

Thnh phn item trong cu trc TVINSERTSTRUCT trn lu thng tin v mc trong cy, n l mt cu trc TVITEM bao gm thnh phn c khai bo nh sau:
typedef UINT struct tagTVITEM { mask; hItem;

HTREEITEM UINT UINT LPSTR int int int int

state; stateMask; pszText;

cchTextMax; iImage; iSelectedImage; cChildren; lParam;

LPARAM } TVITEM;

Trong gi tr mask quy nh mc trn cy c d liu dng no, n bao gm cc gi tr sau:

214

Gi tr TVIF_HANDLE TVIF_STATE TVIF_TEXT TVIF_IMAGE TVIF_SELECTEDIMAGE TVIF_CHILDREN TVIF_PARAM

ngha hItem s ch a d li u state v stateMask s ch a d li u pszText v cchTextMax s ch a d li u iImage s ch a d li u iSelectedImage s ch a d li u cChildren s ch a d li u lParam s ch a d li u

Thng thng ni dung mc trn cy l vn bn nn mask c gi tr TVIF_TEXT v pszText lu ni dung vn bn cng vi cchTextMax lu ti a ca vn bn. Thnh phn state ca cu trc trn quy nh mc tng ng trng thi no, gm c:
Gi tr TVIS_BOLD TVIS_DROPHILITED TVIS_EXPANDED TVIS_EXPANDEDONCE TVIS_SELECTED ngha M c c in m M c c lm sng ln khi ko th M r ng ton b cc nhnh bn trong c a m c Ch m r ng nhnh hi n t i c a m c M c ang c ch n

Thnh phn stateMask quy nh gi tr trng thi trong phn state s t vo hay ly ra. Nu bn cn t hnh nh vo mc ca cy, gi tr iImage cha ch s nh trong i tng CImageList c lin kt vi cy. Nu khng gi tr ny t bng -1 v iImageSelected lu ch s nh khi mc c la chn. Khi bn ly thng tin ca mt mc, thnh phn cChildren cha s mc con ca mc trn cy. lParam cha thng tin do ng dng t nh ngha. Bn phi nh rng mi ln chn mt mc vo cy phi lu gi tr nh danh ca mc s dng cho cc vic khc.

215

6.7.3. M rng v thu hp cy


Sau khi to cy v chn cc mc, bn c th hin th cy ln ca s. Ngi s dng c th bm chut vo mt mc m rng hoc thu hp mc trn cy. Tuy nhin chng ta c th s dng hm thnh vin thc hin theo mu sau:
BOOL Expand( HTREEITEM hItem, UINT nCode );

Trong hItem lu nh danh ca mc cn m rng, nCode quy nh kiu tc ng ln mc bao gm:


Gi tr TVE_COLLAPSE TVE_COLLAPSERESET TVE_EXPAND TVE_TOGGLE ngha Thu h p cy con k t m c th c hi n hItem Thu h p cy con v xa b n M r ng cy con Thay i tr ng thi hi n t i c a cy con

6.7.4. Mt s hm khc ca Tree View


- Xc nh mc ang chn
HTREEITEM GetSelectedItem( );

Hm tr v gi tr kiu HTREEITEM cha thng tin m t v mc ang c chn hin ti. Cu trc ny c m t phn trn. Hm tr v gi tr NULL nu khng c mc no c chn. - t mc chn hin thi
BOOL Select( HTREEITEM hItem, UINT nCode );

Thc hin chn mc c nh danh l hItem. nCode quy nh kiu tc ng ln mc khi chn, bao gm: TVGN_CARET ch thc hin chn mc, TVGN_DROPHILITE mc s c nh du khi ko th, TVGN_FIRSTVISIBLE cy s cun ln hoc xung cho php nhn thy ln u trn ca s. - Ly thng tin mt mc bt k trn cy
BOOL GetItem( TVITEM* pItem );

216

Trong pItem tr ti cu trc kiu TVITEM nh m t, trc khi thc hin hm ny bn phi t gi tr nh danh ca mc cn ly vo thnh phn hItem ca cu trc ny v mask phi c gi tr quy nh thng tin cn ly, bao gm: TVIF_HANDLE, TVIF_STATE, TVIF_TEXT,... - Hm t thng tin cho mt mc trn cy
BOOL SetItem( TVITEM* pItem );

Ging vi hm ly thng tin GetItem(), bn phi t cc gi tr thng tin vo cc thnh phn hItem, mask v cc thnh phn khc tng ng vi gi tr t trong thnh phn mask. - Xa mt mc trn cy
BOOL DeleteItem( HTREEITEM hItem );

Trong hItem cha nh danh ca mc cn xa. Khi xa mt mc th tt c cc mc con bn trong u b xa theo, vy nu bn cn xa ht cy th t hItem bng TVI_ROOT.

6.7.5. X l cc thng ip lin quan n Tree View


Khi truy nhp vo iu khin cy s pht sinh thng ip WM_NOTIFY v gi n ca s cha n. C mt s m thng ip ng vi vic truy xut cy nh sau:
M thng i p TVN_DELETEITEM TVN_ITEMEXPANDING TVN_ITEMEXPANDED TVN_SELCHANGING TVN_SELCHANGED ngha s ki n

C m t m c b xa M t nhnh ang c m hay ng M t nhnh m hay ng M t m c ang c ch n M t m c c ch n

Hm x l thng ip WM_NOTIFY c khai bo nh sau:


afx_msg void func_name (NMHDR *hdr, LRESULT *rs);

Trong func_name l tn ca hm nh x x l thng ip, tham s hdr s tr ti cu trc NMTREEVIEW, cu trc ny khai bo nh sau:

217

typedef struct tagNMTREEVIEW { NMHDR hdr; UINT action; TVITEM itemOld; TVITEM itemNew; POINT ptDrag; } NMTREEVIEW, FAR *LPNMTREEVIEW;

Thnh phn hdr l cu trc chun NMHDR, m thng ip c lu trong thnh phn code ca cu trc hdr. nh danh ca cy pht sinh thng ip tng ng lu trong thnh phn hwndFrom ca cu trc hdr. Gi tr action cu trc trn quy nh thng tin tng ng vi thng ip. Cu trc itemOld lu thng tin ca mc chn trc v itemNew lu thng tin mc ang c chn. Gi tr ta ca chut khi c thng ip lu thnh phn ptDrag. Khi m thng ip l TVN_SELCHANGING v TVN_CHANGED th itemOld cha thng tin mc chn trc v itemNew cha thng tin mc ang chn. Vi thng ip TVN_ITEMEXPANDING v TVN_ITEMEXPANDING th itemNew cha thng tin v mc m ca cy con c m rng. Vi thng ip TVN_DELETEITEM th itemOld cha thng tin ca mc b xa. Trong trng hp thng ip l TVN_SELCHANGING v TVN_ITEMEXPANDING chng ta c th hy b cng vic tng ng bng cch gn gi tr tham s rs l 0 trong hm nh x, ngc li gn 1.

V d 6.9
Lp trnh to mt cy ln ca s, cho php thm, sa, xa mc ca cy bng cc chc nng ca thc n. Chng trnh s c mt hp thoi nhp tn mc, c mt thc n, x l thng ip chn mc trn cy,... Khai bo ti nguyn chng trnh:
218

// Cc nh ngha h ng khai bo ti nguyn : resource.h #define IDD_TREE 174 #define IDR_MENU1 101 #define IDD_DIALOG1 102 #define IDC_EDIT1 1000 #define ID_NEW 40001 #define ID_RENAME 40002 #define ID_DELETE 40003 // Khai bo cc ti nguyn g m : h p tho i v th c n IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 82 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Information of item" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,37,61,50,14 PUSHBUTTON "Cancel",IDCANCEL,98,61,50,14 LTEXT "Enter name of item :",IDC_STATIC,17,20,68,11 EDITTEXT IDC_EDIT1,47,34,117,15,ES_AUTOHSCROLL END // Menu IDR_MENU1 MENU DISCARDABLE BEGIN MENUITEM "New", ID_NEW MENUITEM "Rename", ID_RENAME MENUITEM "Delete", ID_DELETE END

Ni dung chng trnh l:


#include<afxwin.h> #include<afxcmn.h> #include"resource.h" class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CTreeCtrl tree; char iText[50]; CMenu mn; public: CMyWin();

219

void InitControl(); afx_msg void OnSelChanged(NMHDR *hdr,LRESULT *rs); void OnCmd(UINT id); DECLARE_MESSAGE_MAP() }; class CMyDialog : public CDialog { public: CMyDialog(UINT id, CWnd *ow) : CDialog(id,ow){} BOOL OnInitDialog(); void OnOK(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_NOTIFY( TVN_SELCHANGED, IDD_TREE, OnSelChanged ) ON_COMMAND_RANGE( ID_NEW , ID_DELETE , OnCmd ) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP( CMyDialog, CDialog ) ON_COMMAND( IDOK, OnOK ) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 09 - Chuong 06",WS_OVERLAPPEDWINDOW, CRect(100,100,500,500)); mn.LoadMenu(IDR_MENU1); SetMenu(&mn); InitControl(); } void CMyWin::InitControl() { INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_TREEVIEW_CLASSES;

220

InitCommonControlsEx(&ic); RECT rt; GetClientRect(&rt); tree.Create(WS_VISIBLE|WS_CHILD|TVS_HASLINES|TVS_LINESATROOT| TVS_HASBUTTONS,rt,this,IDD_TREE); //Init root item on tree tree.InsertItem("LHLK"); } void CMyWin::OnSelChanged(NMHDR *hdr,LRESULT *rs) { char str1[50],str2[100]; TVITEM tvi; tvi.hItem = (((NMTREEVIEW*)hdr)->itemNew).hItem; tvi.pszText = str1; tvi.cchTextMax = sizeof(str1)-1; tvi.mask = TVIF_TEXT | TVIF_HANDLE; tree.GetItem(&tvi); sprintf(str2,"Current item is %s CDC *dc=GetDC(); dc->SetTextColor(RGB(255,0,0)); dc->TextOut(10,300,str2,strlen(str2)); } void CMyWin::OnCmd(UINT id) { CMyDialog md(IDD_DIALOG1,this); TVINSERTSTRUCT tvs; TVITEM tvi; tvi.hItem = tree.GetSelectedItem(); switch (id) { case ID_NEW: iText[0]=NULL; md.DoModal(); if (strlen(iText)<=0) return; tvi.mask = TVIF_TEXT; tvi.pszText = iText; tvs.hInsertAfter = TVI_LAST; tvs.hParent = (tvi.hItem!=NULL)?tvi.hItem:TVI_ROOT; tvs.item = tvi; ",tvi.pszText);

221

tree.InsertItem(&tvs); break; case ID_RENAME: if (tvi.hItem==NULL) { MessageBox("Ban chua chon muc !"); return; } tvi.mask = TVIF_TEXT | TVIF_HANDLE; tvi.pszText = iText; tvi.cchTextMax = 50; tree.GetItem(&tvi); md.DoModal(); if (strlen(iText)<=0) return; tvi.pszText = iText; tvi.mask = TVIF_TEXT | TVIF_HANDLE; tree.SetItem(&tvi); break; case ID_DELETE: tree.DeleteItem(tvi.hItem); break; } } BOOL CMyDialog::OnInitDialog() { CDialog::OnInitDialog(); CMyWin *mw = (CMyWin*)GetParent(); CEdit *ed = (CEdit*)GetDlgItem(IDC_EDIT1); ed->SetWindowText(mw->iText); return TRUE; } void CMyDialog::OnOK() { CMyWin *mw = (CMyWin*)GetParent(); CEdit *ed = (CEdit*)GetDlgItem(IDC_EDIT1); ed->GetWindowText(mw->iText,50); CDialog::OnOK(); }

Chng ta thc hin to cy trong hm InitControl() ca lp CMyWin, trong ch to mt mc gc ca cy.

222

Hm OnSelChanged() nh x x l la chn mc ca thng ip TVN_SELCHANGED, ly thng tin ca mc ang chn v hin ln qua CDC ca ca s. Hm OnCmd() x l thng ip thc n thc hin cc chc nng thm mt mc mi, i tn mt mc hoc xa mt mc. Vi hai chc nng thm mi hoc i tn mc u phi nhp tn mc qua hp thoi to ra t lp CMyDialog. Lp hp thoi c vit hm OnInitDialog() ly tn mc ang chn v in vo hp nhp tn mc khi sa tn, hm OnOK() ly ni dung tn mc nhp trong iu khin editbox a vo thnh vin iText ca lp ca s. Kt qu chng trnh l:

223

6.8. iu khin Month Calendar


iu khin month calendar cho php ngi dng la chn thng tin ngy thng qua mt giao din rt thun tin, nh bn thy hu ht cc ng dng trn Windows. Mi thi im n hin th cc ngy v tun ca mt hay nhiu thng t bn ch nhn chut vo ngy cn chn. iu khin ny c kt hp t rt nhiu iu khin khc nh popup-menu, up-down,... iu khin month calendar c bao gi bi lp CMonthCalCtrl.

6.8.1. To iu khin Month Calendar


Trc ht bn phi to mt i tng t lp CMonthCalCtrl v gi hm Create theo mu sau:
BOOL BOOL Create( DWORD st, RECT& rt, CWnd* pw, UINT nID ); Create( DWORD st, POINT& pt, CWnd* pw, UINT nID );

Trong tham s st quy nh kiu ca iu khin month calendar, n bao gm cc gi tr chun WS_VISIBLE, WS_CHILD, WS_BORDER v cc gi tr trong bng sau:
Gi tr MCS_DAYSTATE MCS_MULTISELECT MCS_NOTODAY MCS_NOTODAYCIRCLE MCS_WEEKNUMBERS ngha i u khi n s yu c u ngy nh d u c bi t Cho php ch n nhi u ngy trong kho ng Ngy hi n t i khng hi n th Ngy hi n t i khng c quay vng S th t tu n c hi n th

Tham s pw quy nh ca s m cha iu khin ny v nID l s hiu ca iu khin s to ra, nh cc iu khin trc. trn c hai mu khai bo, mu th nht yu cu tham s th hai l rt c kiu RECT quy nh kch thc v v tr ca iu khin, tuy nhin bn c th thc hin mu hai ch yu cu v tr ca iu khin v kch thc s t ng la chn, l tham s pt c kiu POINT. Ch : iu khin month calendar yu cu chng trnh phi np th vin <afxdtctl.h>.
224

6.8.2. Cc hm khc ca CMonthCalCtrl


- Xc nh ngy ang la chn
BOOL BOOL GetCurSel( CTime& refDateTime ) const; GetCurSel( LPSYSTEMTIME pDateTime ) const;

Hm tr v d liu ngy ang chn trn iu khin month calendar, hai mu c kiu tham s khc nhau. Hoc bn chn kiu tr v l CTime hoc l cu trc SYSTEMTIME c khai bo nh sau:
typedef struct _SYSTEMTIME { WORD wYear; - nm WORD wMonth; - thng (1 n 12) WORD wDayOfWeek; - ngy trong tun (0 n 6) WORD wDay; - ngy trong thng (1 n 31) WORD wHour; - gi WORD wMinute; - pht WORD wSecond; - giy WORD wMilliseconds; - phn nghn giy } SYSTEMTIME, *PSYSTEMTIME;

- t la chn ngy Tng t hm trn ta c hm chn ngy nh sau:


BOOL BOOL SetCurSel( const CTime& refDateTime ); SetCurSel( const LPSYSTEMTIME pDateTime );

Chng ta phi a vo ngy cn t qua tham s ca hm. - Xc nh ngy hin ti


BOOL BOOL const; CMonthCalCtrl::GetToday( CTime& refDateTime ) const; CMonthCalCtrl::GetToday( LPSYSTEMTIME pDateTime )

Hm tr v ngy hin ti qua tham s kiu CTime hoc SYSTEMTIME.


225

- t ngy hin ti
void void SetToday( const CTime* pDateTime ); SetToday( const LPSYSTEMTIME pDateTime );

Chng ta phi a vo tham s gi tr ngy cn t hin ti. - Thay i kch thc iu khin trn ca s Trc ht bn phi xc nh kch thc nh nht cha mt thng trn iu khin, s dng hm GetMinReqRect() theo mu sau:
BOOL CMonthCalCtrl::GetMinReqRect( RECT* pRect ) const;

Hm tr v kch thc qua tham s pRect. Khi cn thay i kch thc chng ta s dng hm ca lp CWnd theo mu nh sau:
void CWnd :: MoveWindow( int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE ); void CWnd :: MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE );

Tham s x,y quy nh v tr ca s cn chuyn ti, nWidth v nHeight quy nh kch thc chiu ngang v dc ca iu khin. Gi tr bRepaint s t ng v li ca s hay khng sau khi thay i v dch chuyn. Ch : Nu bn tng kch thc chiu ngang ln gp i so vi ban u th s hin hai thng lin tip cng mt lc trn iu khin ny.

V d 6.10
Lp trnh to mt iu khin month calendar v hin thng bo ngy c chn nu cn qua thc n. Ni dung chng trnh nh sau:
#include<afxwin.h> #include<afxcmn.h> #include<afxdtctl.h> #define IDM_SHOW 174 #define IDM_EXIT 142 #define IDD_MONTH 1976

226

class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMonthCalCtrl mc; CMenu mn; public: CMyWin(); void InitControl(); void OnShowDate(); void OnExit(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP( CMyWin , CFrameWnd ) ON_COMMAND( IDM_SHOW, OnShowDate) ON_COMMAND( IDM_EXIT, OnExit) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 10 - Chuong 06",WS_OVERLAPPEDWINDOW, CRect(100,100,700,500)); mn.CreateMenu(); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_SHOW,"Show date"); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_EXIT,"Exit"); SetMenu(&mn); InitControl(); } void CMyWin::InitControl()

227

{ INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(ic); ic.dwICC = ICC_DATE_CLASSES; InitCommonControlsEx(&ic); RECT rt; rt.left=rt.top=0; rt.right=rt.bottom=0; mc.Create(WS_VISIBLE|WS_CHILD|WS_BORDER,rt,this,IDD_MONTH); mc.GetMinReqRect(&rt); mc.MoveWindow(0,0,rt.right*2+10,rt.bottom); } void CMyWin::OnShowDate() { SYSTEMTIME st; mc.GetCurSel(&st); char s[50]; sprintf(s,"%d/%d/%d",st.wDay,st.wMonth,st.wYear); MessageBox(s,"Date is selected"); } void CMyWin::OnExit() { DestroyWindow(); }

Kt qu chng trnh l:

Khi chn mt ngy v chn chc nng Show date s c kt qu nh sau:

228

6.9. Bi tp
Bi tp 6.1
Lp trnh to mt thanh cng c trn ca s vi cc nt lnh: Hin bi th, Xa, Thot c nh t to bng cng c ca Visual C. Thc hin nh x thng ip chn cc nt lnh hin mt bi th bt k ln ca s, xa ni dung ca s hoc thot khi chng trnh.

Bi tp 6.2
Lp trnh to ba iu khin up-down trn ca s nhp ngy, thng v nm sinh ca bn, nh x thng ip hin gi tr ca cc up-down tng ng l ngy sinh ca bn ln ca s mi ln thay i gi tr.

Bi tp 6.3
Lp trnh to mt iu khin slider nm dc trn ca s cho php nhp gi tr t 0 n 10 v to mt editbox. nh x thng ip hin gi tr vo editbox mi khi thay i gi tr slider.

Bi tp 6.4
Lp trnh to mt iu khin progress bar nm dc trn ca s vi min gii hn l [0,100] v mt editbox. nh x thng ip hin vo editbox gi tr ca progress bar mi ln thay i trn iu khin .

Bi tp 6.5
229

Lp trnh to ba iu khin progress bar nm dc trn ca s vi min gii hn l [0,1000], tng ng l p1, p2, p3. nh x thng ip mi ln dch chuyn chut trn ca s th iu khin p1 s tng, khi p1 tng ht th p2 s tng v p1 v 0, khi p2 tng ht th p3 s tng v p2 v 0, khi p3 tng ht th thot khi chng trnh (ging nh mt mn hnh ci t thng thng).

Bi tp 6.6
Lp trnh to mt iu khin thanh trng thi trn ca s, to cc hin trng thi cc phm CAPS LOCK, SCROLL LOCK, NUM LOCK v hin ta ca chut.

Bi tp 6.7
Lp trnh to mt iu khin tab c 7 th tng ng vi tn 7 ngy trong tun (Thu 2, Thu 3,..., Chu nhat). nh x thng ip hin tn th tab ln ca s mi ln la chn.

Bi tp 6.8
Lp trnh to mt iu khin tree view hin thng tin v mt cy ph h ca gia nh bn, gm ng b, b m, anh em, con ci, chu cht,... nh x thng ip hin tn mc c chn trn cy ln ca s.

Bi tp 6.9
Lp trnh to mt iu khin month calendar cho php chn mt ngy, v mt iu khin editbox. nh x thng ip hin gi tr ngy c chn vo iu khin editbox mi ln bm chut tri ln ca s.

Bi tp 6.10
Lp trnh s dng cc iu khin hc thc hin mt trong cc chng trnh sau: - M phng cc lnh ca MS-DOS v hin cy th mc ln ca s - M phng chng trnh v Paint ca Windows - M phng chng trnh Notepad ca Windows - Tr chi car hai ngi trn my tnh

230

Chng 7 KIN TRC TI LIU/QUAN ST


7.1. Cc khi nim c bn
7.1.1. Kin trc ti liu/quan st
Trong cc chng trc mi chng trnh lp ra u c hai i tng, mt l i tng ng dng t lp CMyApp, hai l i tng ca s t lp CMyWin. Kiu ng dng ny gi l chng trnh ng dng dng ca s (application/window), tip cn theo cch ny chng trnh kh n gin, c mt s phn s do MFC t ng cung cp. Tuy nhin s dng kiu ng dng ca s khng tn dng c cc kh nng cung cp t cc lp c s ca th vin MFC, chng ta phi thc hin mi cng vic hin th d liu ln ca s. Hu ht cc d liu u phi tn ti bn trong ca s ca chng trnh v quy nh cch hin th d liu bi ca s . Tuy nhin trong trng hp cn hin th d liu ln mt khung nhn (quan st) khc ca cng d liu s kh phc tp. Mt chng trnh Windows, d liu l mt khi nim lun tch ri vi vic hin th. Nhng trong kiu ng dng ca s th hai thuc tnh ny gn kt vi nhau trong cng mt lp ca s. Trong mt chng trnh kiu ti liu/quan st, d liu (ti liu vn bn) s tch ri so vi ca s hin th (khung nhn). Chng ta bao gi d liu bn trong lp CDocument v bao gi k thut hin th d liu bn trong lp CView. Lp CView cn qun l cc tng tc gia ngi dng vi d liu. C th thy kin trc ti liu/quan st cng nh hai phn d liu v m lnh trong mt chng trnh.

231

Khi to mt chng trnh kiu ti liu/quan st, lp ti liu phi c dn xut t lp CDocument v lp quan st c dn xut t lp CView. Khi to mt chng trnh kiu ti liu/quan st, bn vn phi to mt lp khung ca s ng dng (frame window) v mt lp ng dng. Tuy nhin lp khung ng dng s ng vai tr hon ton khc vi nhng v d chng trc, n ch gi vai tr l mt khung ca chng trnh ng dng, cn mi hin th trn ca s ng dng s do lp CView thc hin. Lp CView s hon ton ln lp CFrameWnd.

7.1.2. Khi nim v ti liu


Ti liu (document) l d liu (data) c x l bi chng trnh ca bn. Khi nim ti liu y khng ch l vn bn, n bao gm cc nh dng d liu m chng trnh x l. V d nh mt tp vn bn, mt tp nh, mt tp m thanh,... Trong kin trc ti liu/quan st c hai dng chng trnh l dng SDI (Single Document Interface) hoc dng MDI (Multi Document Interface). Dng MDI l mt ca s ti mt thi im c th cha nhiu khung nhn hin th cc ti liu, cn dng SDI mt ca s ch cha mt khung nhn ti mt thi im.

7.1.3. Khi nim v quan st


Mt quan st (hay cn gi l khung nhn) s hin th mt ti liu. Khung nhn l mt biu din dng vt l ca d liu trong chng trnh. Vic nh x ti liu ln khung nhn l mt ti nhiu, c ngha mt ti liu c th c hin th trn nhiu khung nhn, nhng mt khung nhn ch hin th c mt ti liu gn vi n. Khung nhn khng ch gii hn l hin th trn mn hnh, n bao gm c nhng biu din dng vt l ca d liu trn cc thit b xut thng tin nh my in. Vy ti liu l d liu nguyn thy v khung nhn l mt biu din c th ca d liu. Minh ha v kin trc ti liu/quan st:

232

7.1.4. Qun l lu tr ti liu


Cc lp ti liu/quan st cung cp bi th vin MFC s t ng lu tr ti liu vo a, x l lu tr ny gi l serialization. Khi nim serialization ny th hin s khng kht gia vic lu tr ti liu vo a v ly ra khi cn. K thut cho khi nim qun l lu tr ny c xy dng bn trong lp CDocument. Serialization l khi nim quan trng bi v n nh ngha nhng c tnh ca kin trc ti liu/quan st. Nu bn lp chng trnh kiu ti liu/quan st nhng khng cung cp qun l lu tr theo khi nim ny th cha tht s l mt ng dng ti liu/quan st.

7.1.5. Khi nim to lp i tng ng


Trong chng trnh kiu ti liu/quan st, cc i tng dng ng (dynamic). l khi chy chng trnh cc i tng ca s khung ng dng, ti liu, khung nhn c to lp ti thi im thi hnh. Khc vi cc ng dng ca cc chng trc, cc i tng c to ra ngay ti thi im lp trnh. Vic to lp i tng ng cn thit y bi v khi mt ti liu c np vo t a hoc c to mi th mt khung nhn phi c to ra tng ng. lm vic ny chng ta s dng hai macro nh sau:
DECLARE_DYNCREATE( class_name )

233

Macro ny xc lp vic khai bo mt lp s c to lp ng ti thi im thi hnh, tn lp cn t l class_name v vit macro ny vo bn trong ( phn u tin) khai bo ca lp .
IMPLEMENT_DYNCREATE( class_name, base_class_name )

Macro ny xc lp vic ci t c th mt lp ng, class_name l tn lp cn xc lp v base_class_name l tn lp c s ca n. Vit macro ny vo u ca phn vit m lnh cc thnh vin hm ca lp ng tng ng. Kt hp hai macro ny vi nhau cho php mt lp ng c th s dng nh mt tham s ca macro RUNTIME_CLASS sau:
RUNTIME_CLASS( class_name )

Trong class_name l tn lp ng ti thi im thi hnh c xc lp bi hai macro trn. Macro RUNTIME_CLASS tr v con tr ti cu trc CRuntimeClass, cu trc ny lu thng tin v lp ca i tng ang thi hnh trong chng trnh.

7.2. Cch to ng dng vi kin trc ti liu/quan st


to mt ng dng kiu ti liu/quan st chng ta thc hin theo cc bc sau: Bc 1: Dn xut xy dng lp cung cp cho chng trnh: Lp ng dng CMyApp t lp CWinApp. Lp khung ca s CMyWin t lp CFrameWnd. Lp ti liu CMyDoc t lp CDocument. Lp CMyView t lp CView. Bc 2: Cho php to lp ng cc lp CMyWin, CMyDoc v CMyView. Bc 3: To mt mu (template) lin kt cc lp CMyWin, CMyDoc v CMyView vi nhau. Bc 4: Phn tch c php v x l dng lnh. Bc 5: Np chng mt s hm thnh vin thc hin nh CObject :: Serialize() v CView :: OnDraw().

234

7.2.1. Dn xut lp CWinApp v CFrameWnd


Xy dng hai lp CMyApp v CMyWin dn xut t hai lp CWinApp v CFrameWnd tng t nh chng ta lm cc chng trc. Tuy nhin lp CMyWin s c t thnh vin hm hn v lp CMyApp c thm mt s hm. Lp CMyWin phi l lp ng nn ta s DECLARE_DYNCREATE trong khai bo lp nh sau:
class { DECLARE_DYNCREATE( CMyWin ) ... public: CMyWin(); ... DECLARE_MESSAGE_MAP() }; CMyWin : public CFrameWnd

dng

macro

DECLARE_DYNCREATE y l phm vi private, tuy nhin bn c th t n phm vi protected hoc pubic nu cn.

7.2.2. Dn xut lp CDocument


Lp ti liu ca chng trnh phi c dn xut t lp CDocument, lp ny cng phi t lp ng bng macro DECLARE_DYNCREATE. Lp ny s nhn v x l cc lnh lin quan n ti liu v cung cp nh x thng ip phn nh kt qu x l . Lp ti liu cha nhiu hm thnh vin x l d liu, phi vit mt s hm trong lp ny thc hin theo ca chng ta. Mt hm lun c vit trong lp ny l OnNewDocument(), mu khai bo hm nh sau:
virtual BOOL CDocument :: OnNewDocument( );

Trong hm ny bn phi gi n hm ca lp c s CDocument v tr v gi tr TRUE nu thnh cng, ngc li tr v FALSE.


235

Mt hm khc cng c vit l Serialize(), n l thnh vin ca lp CObject. Mu khai bo lp CMyDoc nh sau:
class { DECLARE_DYNCREATE( CMyDoc ) ... public: CMyDoc(); BOOL void ... DECLARE_MESSAGE_MAP() }; OnNewDocument(); Serialize( CArchive &arch); CMyDoc : public CDocument

7.2.3. Dn xut lp CView


Lp CView c chc nng hin th ti liu trong lp CDocument, khung nhn ny s nm ln ca s khung ng dng v da vo cc chc nng ca n nh thay i kch thc. Lp dn xut CMyView ca chng trnh c th k tha trc tip t lp CView hoc mt trong cc lp dn xut t n nh CScrollView, CCtrlView,... Lp CMyView cng phi c xc lp l lp ng bng macro DECLARE_DYNCREATE v thu thp cc tng tc ca ngi dng x l ti liu. Lp CView c rt nhiu thnh vin hm, trong chng ta phi vit hm OnDraw(). Hm ny s c gi mi ln cn cp nht hin th d liu. V chc nng hm OnDraw() cng tng t hm OnPaint() trong lp ng dng dng ca s trc y. Mu khai bo hm ny nh sau:
virtual void CView :: OnDraw( CDC* pDC ) = 0;

236

Nh vy hm OnDraw() l mt hm thun o, c ngha l khi bn xy dng lp CMyView dn xut t lp CView s phi vit li hm ny mi tr thnh lp dng c (lp CView l lp tru tng, khng to i tng t lp ny c). Tham s DC trong hm s tr n ng cnh thit b hin ti ca khung nhn. Chng ta s dng tham s ny thc hin biu din ti liu ln ca s khung nhn tng ng. Mu khai bo lp CMyView nh sau:
class { DECLARE_DYNCREATE( CMyView ) ... public: void ... DECLARE_MESSAGE_MAP() }; OnDraw(CDC *DC); CMyView : public CView

Trc khi ci t c th cc hm cho cc lp trn trong tp m lnh (CPP), chng ta phi xc lp cc lp c th to lp ng khi thi hnh bng cc macro sau:
IMPLEMENT_DYNCREATE( CMyWin , CFrameWnd ) IMPLEMENT_DYNCREATE( CMyDoc , CDocument ) IMPLEMENT_DYNCREATE( CMyView , CView )

7.2.4. To mu ti liu (document template)


Sau khi to xong cc lp theo yu cu nh trn, bn s dng cc lp to mt mu ti liu. Mu ti liu ny thc hin lin kt cc lp khung ca s, ti liu, khung nhn vi nhau v cho php chng lm vic nh mt n v thng nht. Chng ta c th to mu a ti liu hoc mu n ti liu

237

tng ng vi kiu ng dng MDI hoc SDI. Trong v d ca chng ny chng ta s lm vic vi mu n ti liu. Mu n ti liu l mt i tng to ra t lp CSingleDocumentTemplate, lp ny ch c duy nht mt phng thc to khai bo theo mu sau:
CSingleDcumentTemplate :: CSingleDocTemplate( UINT nID, CRuntimeClass* CRuntimeClass* CRuntimeClass* pDocClass, pFrameClass, pViewClass );

Trong nID l s hiu ca ti nguyn s dng trong mu ny, cc ti nguyn bao gm thc n v bng phm tt cung cp cho ca s khung ng dng, biu tng v bng k t cha tn ca nhiu mc d liu lin quan ti chng trnh. pDocClass l mt con tr ti lp ti liu, pFrameClass l con tr ti lp khung ng dng, pViewClass l con tr ti lp khung nhn. Cc con tr ny nhn c bng cch s dng macro RUNTIME_CLASS nh sau:
RUNTIME_CLASS( class_name )

Ngoi ra, s hiu nID cha thm cc ti nguyn xu k t theo th t sau: Tiu ca s khung ng dng. Tn mc nh ca ti liu, nu khng th my s ly l Untitled. Tn kiu ti liu, cn khi chng trnh x l nhiu kiu ti liu khc nhau. Tn ca cc kiu tp tin c s dng trong chng trnh. Lc tn tp theo phn m rng, v d nh .TXT. Kiu tp s dng trong ng k h thng. Tn ca kiu tp ti liu s dng trong ng k h thng. Mi xu k t cho mt thnh phn m t trn phi cch nhau du xung dng (\n). Nu l xu rng th bn cng phi vit du xung dng. Ti nguyn xu k t c khai bo theo t kha STRINGTABLE trong tp RC nh sau:

238

STRINGTABLE { stringID1 , xu k t stringID2 , xu k t ... stringIDn , xu k t }

V d cho mt khai bo ti nguyn xu k t nh sau:


STRINGTABLE { IDR_MYWIN Doc/view program \n DocName \n DocType \n DocFileType (*.doc) \n .doc \n FileType \n NameType }

Trong IDR_MYWIN l s hiu ti nguyn nh ngha trong tp Resource.h bi ch dn #define, Doc/View program l tiu ca ng dng, DocName l tn ti liu mc nh, DocType l tn kiu ti liu, tn kiu tp l DocFileType (*.doc), phn m rng ca tp l .doc, tn kiu ti liu v tn kiu tp ng k trong h thng s l FileType v NameType.

7.2.5. Khi to ng dng


Trong lp ng dng CMyApp dn xut t lp CWinApp chng ta phi vit hm InitInstance() khi to mt ng dng, nh thc hin cc v d trc. Tuy nhin trong kiu ng dng ti liu/quan st ny vic khi to s thc hin: To mt i tng mu ti liu. Gn i tng vo ng dng. Phn tch c php v x l cc dng lnh. Mu hm khi to ng dng c vit nh sau:

239

BOOL {

CMyApp :: InitInstance()

CSingleDocTemplate *DocPtr = new CSingleDocTemplate( IDR_MYWIN, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMyWin), RUNTIME_CLASS(CMyView) ); AddDocTemplate(DocPtr); EnableShellOpen(); RegisterShellFileTypes(); CCommandLineInfo CLInfo; ParseCommandLine(CLInfo); if (!ProcessShellCommand(CLInfo)) return FALSE; return TRUE; }

Bin tr DocPtr kiu CSingleDocumentTemplate tr n i tng c to ra bi lnh new tng ng. S dng hm to vi cc tham s l cc bin tr lp, nhn c qua macro RUNTIME_CLASS. Sau gi hm AddDocTemplate() thm mu ti liu ny vo ng dng, hm c mu khai bo nh sau:
void CWinApp :: AddDocTemplate( CDocTemplate* pTemplate );

Trong pTemplate l con tr n i tng lp CDocTemplate, lp ny l lp c s ca lp CSingleDocumentTemplate. Sau khi thm mu ti liu, bn phi gi hm EnableShellOpen() v RegisterShellFileTypes(), hai hm ny c mu sau:
void CWinApp :: EnableShellOpen( ); void CWinApp :: RegisterShellFileTypes( BOOL bCompat = FALSE );

240

Hm EnableShellOpen() cho php ngi dng khi ng ng dng bng cch bm p chut vo biu tng ca kiu tp tin tng ng. Hm RegisterShellFileTypes() ng k kiu ti liu ca ng dng vo h thng Windows. Nu gi tr tham s bCompat l TRUE th cc tp tin to ra bi ng dng c th in ra bng cch ko th vo i tng my in. Ch : Thng tin ng k c cung cp bi xu k t trong ti nguyn (STRINGTABLE) v c s dng khi to i tng mu ti liu. Tip theo to mt i tng kiu CCommandLineInfo lu thng tin v tham s dng lnh khi thc hin chng trnh. Tham s dng lnh do ngi dng khi ng ng dng a vo, c th dng m tp ti liu ngay khi khi ng. Hm ParseCommandLine() phn tch c php ca dng lnh, hm ProcessShellCommand() x l dng lnh v xc nh c hp l hay khng. Nu hm ny tr v gi tr FALSE th hm khi to InitInstance() ng dng phi tr v gi tr FALSE, ngc li tr v gi tr TRUE.

V d 7.1
Lp chng trnh dng ti liu/quan st thc hin v ln ca s hnh ch nht. Chng trnh c t chc thnh 4 tp: tp cha nh ngha hng ti nguyn (resource.h), tp cha khai bo ti nguyn (*.rc), tp khai bo cc lp ca chng trnh (*.h) v tp ni dung chng trnh (*.cpp). Ni dung tp nh ngha hng ti nguyn resource.h nh sau:
#define IDR_MYWIN #define ID_FILE_EXIT 1 40003

Ni dung tp khai bo ti nguyn thc n v xu k t main.rc l:


#include "afxres.h" #include "afxres.rc" #include "resource.h" IDR_MYWIN MENU BEGIN POPUP "File" BEGIN DISCARDABLE

241

MENUITEM "Exit", ID_FILE_EXIT END END // String Table STRINGTABLE DISCARDABLE BEGIN IDR_MYWIN "Chuong trinh DocView - Vidu01/Chuong7\nLHLK\n\nLHK Type (*.lhk)\n.lhk\nFileType\nNameType" END

Ni dung tp khai bo lp ca chng trnh main.h l:


class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { DECLARE_DYNCREATE( CMyWin ) }; class CMyDoc : public CDocument { DECLARE_DYNCREATE( CMyDoc ) }; class CMyView : public CView { DECLARE_DYNCREATE( CMyView ) public: void OnDraw(CDC *DC); };

Ni dung tp chng trnh chnh main.cpp l:


#include<afxwin.h> #include"main.h" #include"resource.h" CMyApp theApp; IMPLEMENT_DYNCREATE( CMyWin , CFrameWnd ) IMPLEMENT_DYNCREATE( CMyDoc , CDocument ) IMPLEMENT_DYNCREATE( CMyView , CView ) BOOL CMyApp::InitInstance() {

242

CSingleDocTemplate *DocPtr = new CSingleDocTemplate( IDR_MYWIN, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMyWin), RUNTIME_CLASS(CMyView)); AddDocTemplate(DocPtr); EnableShellOpen(); RegisterShellFileTypes(); CCommandLineInfo CLInfo; ParseCommandLine(CLInfo); if (!ProcessShellCommand(CLInfo)) return FALSE; return TRUE; } void CMyView::OnDraw(CDC *DC) { CBrush b; b.CreateSolidBrush(RGB(255,0,0)); DC->FillRect(CRect(50,50,200,150),&b); }

Trong v d ny chng ta ch thc hin ci t hai hm thnh vin l hm InitInstance() ca lp CMyApp khi to ng dng v hm OnDraw() ca lp CMyView v hnh ch nht theo yu cu. Ch : Trong tp khai bo ti nguyn main.rc bn phi np hai tp ti nguyn chun ca MFC nh sau: <afxres.h> v <afxres.rc>. Kt qu chng trnh s nh sau:

243

7.3. Lu tr v c ti liu trn a


Mt cng vic quan trng trong lp trnh kin trc ti liu/quan st l lu tr ti liu v c ti liu trn a. Lp i tng CObject cha hm thnh vin Serialize() s c t ng gi thc hin khi mt ti liu c c hoc lu tr (ghi). Lp i tng CArchive s nm gi v qun l s hiu tp tin trn a thc hin c v ghi. Lp ny np chng hai ton t nhp v xut (<< v >>) cho vic thc hin c/ghi tp theo kiu d liu ca ng dng. Trong chng trnh kiu ti liu/quan st, hm CObject::Serialize() c gi mi khi thc hin c/ghi ti liu. Hm c khai bo nh sau:
virtual void CObject :: Serialize( CArchive& ar );

Trong tham s ar l i tng lp CArchive nh ngha dng vo/ra cho d liu ca ti liu. Trong lp ti liu CMyDoc phi vit hm ny thc hin vic c/ghi d liu trn tp. bit ti thi im x l dng vo/ra cho ti liu trn i tng ar ang c c hoc ghi chng ta s dng hai hm sau:
BOOL BOOL CArchive :: IsLoading( ) const; CArchive :: IsStoring( ) const;

Hm IsLoading() tr v gi tr TRUE nu ti liu ang c c, tng t hm IsStoring() tr v gi tr TRUE nu ti liu ang c ghi. Trong phin bn vit hm Serialize() ca lp CMyDoc chng ta thc hin ton t << ghi d liu v >> c d liu.

7.4. Mt s hm lin quan


7.4.1. Hm cp nht ni dung ti liu ln khung nhn
Lp ti liu CDocument c cha hm cp nht ti liu ln khung nhn l UpdateAllViews(), chng ta gi hm ny mi khi ti liu c thay i. Hm c khai bo nh sau:
void UpdateAllViews( CView* pV,LPARAM lP=0L,CObject* pO=NULL );

244

Trong tham s pV l con tr n i tng lp CView, l i tng khung nhn s c cp nht. Nu tham s ny l NULL th tt c cc khung nhn ca ti liu s c cp nht. Tham s lP kiu LPARAM v pO l con tr kiu CObject ti u vic cp nht ni dung. Gi hm UpdateAllViews() s thc hin hm CView::OnUpdate(), nu cn bn c th vit hm ny thc hin ti u cp nht.

7.4.2. t trng thi d liu


Khi ti liu c thay i bn phi gi hm SetModifiedFlag() thay i trng thi cho ti liu . Sau khi hm ny c gi, ngi dng s c hi c th lu gi ti liu trc khi hy b n. Hm ny c mu khai bo nh sau:
void CDocument :: SetModifiedFlag( BOOL bModified = TRUE );

Tham s bModified bng TRUE nu mun t c thay i ti liu, ngc li t bng FALSE.

7.4.3. Xc nh ti liu trn khung nhn


xc nh i tng ti liu ang gn trn khung nhn chng ta s dng hm GetDocument() ca lp CView. Hm c khai bo nh sau:
CDocument* CView :: GetDocument( ) const;

Hm tr v con tr ti i tng ti liu gn trn khung nhn c gi. Chng ta s dng hm ny xc nh ti liu trong x l, v d trong hm OnDraw() thc hin biu din ti liu ln khung nhn.

V d 7.2
Lp chng trnh kiu ti liu/quan st cho php v cc ng gp khc theo cc im nhn chut tri trn khung nhn. Thc hin hy b cc nt v, to bn v mi, lu bn v, m bn v c, chn mu trn hp thoi mu. Cc chc nng ny chn qua thc n chng trnh. D liu v ng gp khc ch cn cc ta im, s lng im do trong lp ti liu CMyDoc chng ta khai bo hai thnh vin lu hai d liu ny: s im v mng lu cc im v.

245

chn mu trn hp thoi chng ta s dng i tng lp CColorDialog nh cp trong chng trc. Cc chc nng to mi, lu gi, ng, m ti liu s c nh x thng ip trong lp ng dng CMyApp. Cn li s nh x trong lp CMyView. Ni dung tp nh ngha hng ti nguyn resource.h l:
#define IDR_MYWIN #define ID_FILE_SAVEAS #define ID_FILE_EXIT #define ID_EDIT_COLOR 102 40006 40007 40008

Ni dung tp khai bo ti nguyn main.rc l:


#include "afxres.h" #include "afxres.rc" #include "resource.h" IDR_MYWIN MENU DISCARDABLE BEGIN POPUP "File" BEGIN MENUITEM "New\tCtrl+N", ID_FILE_NEW MENUITEM "Open\tCtrl+O", ID_FILE_OPEN MENUITEM SEPARATOR MENUITEM "Save\tCtrl+S", ID_FILE_SAVE MENUITEM "Save as", ID_FILE_SAVEAS MENUITEM SEPARATOR MENUITEM "Exit\tCtrl+E", ID_FILE_EXIT END POPUP "Edit" BEGIN MENUITEM "Undo\tCtrl+U", ID_EDIT_UNDO MENUITEM "Color\tCtrl+C", ID_EDIT_COLOR END END // Accelerator IDR_MYWIN ACCELERATORS DISCARDABLE BEGIN "C", ID_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT "E", ID_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT "U", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT

246

END // Icon IDR_MYWIN ICON DISCARDABLE "icon1.ico" // String Table STRINGTABLE DISCARDABLE BEGIN IDR_MYWIN "Chuong trinh Vidu02/Chuong7\nKhanh\n\nLHK Type (*.lhk)\n.lhk\nFileType\nNameType" END

Ni dung tp biu tng chng trnh icon1.ico l:

Ni dung tp khai bo cc lp ca chng trnh main.h l:


#define MAXPOINT 150 class CMyApp : public CWinApp { public: BOOL InitInstance(); afx_msg void OnFileSaveAs(); afx_msg void OnFileExit(); DECLARE_MESSAGE_MAP() }; class CMyWin : public CFrameWnd { DECLARE_DYNCREATE(CMyWin) }; class CMyDoc : public CDocument { DECLARE_DYNCREATE(CMyDoc)

247

public: int mCount; COLORREF mColor; CPoint mPoint[MAXPOINT]; CMyDoc(); BOOL OnNewDocument(); void OnEditUndo(); void OnEditColor(); void Serialize(CArchive &ar); DECLARE_MESSAGE_MAP() }; class CMyView : public CView { DECLARE_DYNCREATE(CMyView) public: void OnDraw(CDC *DC); afx_msg void OnLButtonDown(UINT nFlags,CPoint point); DECLARE_MESSAGE_MAP() };

Ni dung tp m lnh chng trnh main.cpp l:


#include<afxwin.h> #include<afxdlgs.h> #include"resource.h" #include"main.h" CMyApp theApp; IMPLEMENT_DYNCREATE(CMyWin,CFrameWnd) IMPLEMENT_DYNCREATE(CMyDoc,CDocument) IMPLEMENT_DYNCREATE(CMyView,CView) BEGIN_MESSAGE_MAP(CMyApp,CWinApp) ON_COMMAND(ID_FILE_NEW,CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN,CWinApp::OnFileOpen) ON_COMMAND(ID_FILE_SAVEAS,OnFileSaveAs) ON_COMMAND(ID_FILE_EXIT,OnFileExit) END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CMyDoc,CDocument) ON_COMMAND(ID_EDIT_UNDO,OnEditUndo) ON_COMMAND(ID_EDIT_COLOR,OnEditColor) END_MESSAGE_MAP()

248

BEGIN_MESSAGE_MAP(CMyView,CView) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { CSingleDocTemplate *p=new CSingleDocTemplate( IDR_MYWIN, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMyWin), RUNTIME_CLASS(CMyView)); AddDocTemplate(p); EnableShellOpen(); RegisterShellFileTypes(); CCommandLineInfo cmd; ParseCommandLine(cmd); if (!ProcessShellCommand(cmd)) return FALSE; return TRUE; } void CMyApp::OnFileSaveAs() { } void CMyApp::OnFileExit() { CWnd *mw = GetMainWnd(); mw->DestroyWindow(); } CMyDoc::CMyDoc() { mCount=0; mColor=RGB(255,0,0); } void CMyDoc::Serialize(CArchive &ar) { int i; if (ar.IsLoading()) { ar>>mCount; ar>>mColor;

249

for (i=0;i<mCount;i++) ar>>mPoint[i]; } else { ar<<mCount; ar<<mColor; for (i=0;i<mCount;i++) ar<<mPoint[i]; } } BOOL CMyDoc::OnNewDocument() { return CDocument::OnNewDocument(); } void CMyDoc::OnEditUndo() { if (mCount>0) mCount-=1; UpdateAllViews(NULL); } void CMyDoc::OnEditColor() { CColorDialog cd; if (cd.DoModal()==IDOK) { mColor = cd.GetColor(); UpdateAllViews(NULL); } } void CMyView::OnDraw(CDC *DC) { CMyDoc *doc = (CMyDoc*)GetDocument(); CPen p; p.CreatePen(PS_SOLID,1,doc->mColor); DC->SelectObject(&p); DC->MoveTo(doc->mPoint[0]); for (int i=1;i<doc->mCount;i++) DC->LineTo(doc->mPoint[i]); } void CMyView::OnLButtonDown( UINT nFlags, CPoint point ) { CMyDoc *doc = (CMyDoc*)GetDocument(); if (doc->mCount==MAXPOINT) { MessageBox("Nhieu diem qua...!"); return;

250

} doc->mPoint[doc->mCount]=point; doc->mCount++; doc->SetModifiedFlag(); doc->UpdateAllViews(NULL); }

Kt qu chng trnh s nh sau:

7.5. Bi tp
Bi tp 7.1
Lp chng trnh kiu ti liu/quan st nhp vn bn t bn phm. Mi vn bn c th chn mu ch, phng ch hin th trn ca s cng nh lu vo tp. Cc chc nng thc hin qua la chn thc n.

Bi tp 7.2
Lp trnh kiu ti liu/quan st cho php v cc hnh c bn ln ca s nh: hnh ch nht, hnh trn/elp, hnh qut, ng thng. Ngoi ra cho php chn mu v, mu t, kiu t thc hin. D liu mi hnh v bn lu gm cc phn sau: k hiu hnh v (C, T, Q, D,...); mu v, mu t, kiu t, d liu v ta im ca hnh .

Bi tp 7.3
251

Lp trnh kiu ti liu/quan st thc hin gii phng trnh bc hai, d liu gm cc h s a,b,c v cc chc nng nhp d liu, gii phng trnh v thng bo kt qu.

Bi tp 7.4
Lp trnh kiu ti liu/quan st thc hin gii bi ton ma trn gm cc chc nng sau: nhp ma trn mi, chuyn v ma trn, tnh ly tha ma trn vung, cho ha ma trn,... Cc chc nng thc hin qua thc n. Bn phi xy dng lp CMyView hin th ma trn ln khung nhn theo hng, ct. D liu lu tr s l ma trn nhp vo.

Bi tp 7.5
Lp trnh kiu ti liu/quan st thc hin m phng cc lnh ca MS-DOS v hin th cy th mc ln mn hnh. S dng lp CTreeView hin th cy th mc. D liu cy th mc bn t khai bo di dng cy nh sau: - Mi nt tng ng vi mt th mc. - Trong mt nt c cc phn sau: con tr n nt m (th mc m), con tr n con u (th mc con u tin), con tr n em k (th mc k tip vi n cng cp) v phn ni dung tn ca nt . Cc lnh thc hin nhp vo qua mt editbox pha di ca s.

Bi tp 7.6
Lp trnh kiu ti liu/quan st m phng tr chi life. Life do tp ch Scientific American a ra t 10/1970. Tr chi m phng vic sinh ra, cuc sng, cht v pht sinh li cc t bo trong v tr bao gm mng hai chiu cc hnh vung. Mi hnh vung i din cho mt t bo, mu xanh tng ng vi t bo sng, mu trng l t bo rng. Ti mi t bo sau khi cht coi nh t bo l rng. Mt t bo s c cc hng xm bn cnh c xc lp nh sau: gm c 8 t bo trn, di, tri, phi v 4 gc ng cho lin k. Mt bc pht trin sang th h mi theo quy lut sau: Mt t bo sng (mu xanh) c chnh xc hai hay ba hng xm s sng qua th h tip theo.
252

Mt t bo rng c chnh xc hai hng xm s c sinh ra trong th h tip theo. Mt t bo sng c t hn hai hay nhiu hn ba hng xm s cht trong th h tip theo. Cc chc nng khi to th h ban u, pht trin th h tip theo,... u thc hin qua thc n hoc phm tt.

253

Chng 8 VO RA D LIU VI A V MY IN
8.1. Vo ra d liu trn a v lp CStdioFile
8.1.1. Gii thiu vo ra a
Nh chng ta bit (trnh by trong chng 7) cng vic lu tr v c d liu trn a c thc hin mt cch t ng thng qua hm Serialize() ca lp CDocument trong th vin MFC. Trong hm ny c mt tham s ar kiu lp CArchive nm gi s hiu tp tin cn c v ghi. Mi thao tc c ghi d liu u thc hin trn i tng ar ny. i vi trng hp chng trnh c kin trc ca s (application/window) th vic c ghi tp c th thc hin qua i tng lp CStdioFile. thc hin c ghi mt tp trn a chng ta phi lm nhng thao tc sau: - Xc nh tn tp cn thc hin. - M tp c hoc ghi. - Thc hin c hoc ghi theo ch m. - ng tp. Tuy nhin cng vic ny s c t ng thc hin tng ng vi cc s hiu chc nng ID_FILE_SAVE hoc ID_FILE_OPEN ca h thng, bt buc trong chng trnh kiu ti liu/quan st phi c nh ngha cc chc nng trong thc n. Trong chng 8 ny chng ti mun trnh by mt cch khc thc hin c ghi d liu trn a mt cch trc tip, theo ngha chng ta phi thc hin ht cc thao tc trnh by trn cho mt qu trnh c ghi tp.

254

8.1.2. Lp CStdioFile
Th vin MFC c cung cp mt lp lm vic ny trc tip l lp CStdioFile, lp ny dn xut t lp CFile v c cc thnh vin nh sau: - Thnh vin d liu
m_hFile

cha s hiu th tp khi lm vic trn h iu hnh. - M tp


virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );

Trong tham s lpszFileName l tn tp (c th c c ng dn), cn tham s nOpenFlags quy nh ch m tp bao gm:


Gi tr quy nh CFile::modeCreate CFile::modeNoTruncate CFile::modeRead CFile::modeReadWrite CFile::modeWrite CFile::typeText CFile::typeBinary ngha T o t p m i, n u t p c th s b xa K t h p v i modeCreate th s khng xa t p c M t p ch c M t p c v ghi M t p ch ghi Ki u c ghi t p s l vn b n text Ki u c ghi l nh phn

Tham s pError s cha kt qu li nu c, nu khng cn bn c th b qua tham s ny v mc nh l NULL. - ng tp


virtual void Close( );

- c tp
virtual UINT Read( void* Buf, UINT Size ); DWORD ReadHuge( void* Buf, DWORD Size ); virtual LPTSTR BOOL ReadString( LPTSTR lpsz, UINT nMax ); ReadString(CString& rString);

255

Tham s Buf tr n vng nh cha d liu c ra, Size l s byte cn c. Hm Read() s c mt ln nh hn 64Kb, hm ReadHuge() c th c vi s lng byte nhiu hn. Hai hm u tr v s byte thc s c thnh cng. Kt qu tr v c th t hn s byte yu cu nu tp ht d liu. Hm ReadString() c d liu dng vn bn vi tham s lpsz l a ch xu v nMax l di ti a c. - Ghi tp
virtual void void virtual void Write( const void* Buf, UINT Size ); WriteHuge( const void* Buf, DWORD Size ); WriteString( LPCTSTR lpsz );

Tham s Buf tr n vng nh cha d liu cn ghi, Size l s byte cn ghi t vng nh vo tp. Tng t nh c tp, hm Write() ch ghi mt ln nh hn 64Kb v hm WriteHuge() c th ghi hn. Hai hm u tr v s byte thc s ghi thnh cng. Hm WriteString() ghi d liu xu nm trong tham s lpsz vo tp. - y vng m ln tp
virtual void Flush( );

Sau mi ln ghi tp cc bn nn nh gi hm ny thc hin chuyn d liu ghi t vng m vo tp mi c hon thnh. Nu gi hm ng tp Close() th khng cn gi hm ny. - Chuyn u c/ghi trn tp
virtual LONG Seek( LONG lOff, UINT nFrom );

Tham s lOff quy nh khong cn dch chuyn, nFrom quy nh v tr bt u dch chuyn bao gm:
Gi tr CFile::begin CFile::current CFile::end ngha ut p Vv tr hi n th i Cu i t p

256

- Xc nh di tp (tnh bng byte)


virtual DWORD GetLength( ) const;

- Xc nh v tr hin thi ca u c/ghi tp


virtual DWORD GetPosition( ) const;

- i tn tp
static void Rename( LPCTSTR OldName, LPCTSTR NewName );

Tham s OldName l tn c ca tp cn i (bao gm c ng dn nu cn), NewName l tn mi (khng c ng dn). - Xa tp


static void Remove( LPCTSTR lpszFileName );

V d 8.1
Lp trnh v mt h trc ta ln ca s, cho php nhn chut tri nhp cc im v ghi vo tp di hai dng vn bn v nh phn. Ni dung chng trnh nh sau:
#include<afxwin.h> #include<afxdlgs.h> #define MAXPOINT 500 #define ID_SAVE 174 #define ID_OPEN 142 #define ID_EXIT 149 class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { private: int nSize; CPoint pt[MAXPOINT]; public: CMyWin(); void OnSave();

257

void OnOpen(); void OnExit(); afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags,CPoint pt); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_COMMAND(ID_SAVE,OnSave) ON_COMMAND(ID_OPEN,OnOpen) ON_COMMAND(ID_EXIT,OnExit) ON_WM_LBUTTONDOWN() ON_WM_PAINT() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { nSize=0; Create(NULL,"Vi du 01 - Chuong 08"); CMenu mn; mn.CreateMenu(); mn.AppendMenu(MF_BYCOMMAND|MF_STRING,ID_OPEN,"Open"); mn.AppendMenu(MF_BYCOMMAND|MF_STRING,ID_SAVE,"Save"); mn.AppendMenu(MF_BYCOMMAND|MF_STRING,ID_EXIT,"Exit"); SetMenu(&mn); } void CMyWin::OnExit() { DestroyWindow(); } void CMyWin::OnOpen() {

258

CStdioFile f; CFileDialog fd(TRUE); if (fd.DoModal()==IDOK) { if (f.Open(fd.GetPathName(),CFile::modeRead)) { f.Read(&nSize,sizeof(nSize)); if (nSize>=MAXPOINT) nSize=MAXPOINT; for (int i=0;i<nSize;i++) f.Read(&pt[i],sizeof(pt[i])); f.Close(); InvalidateRect(NULL); } } } void CMyWin::OnSave() { CStdioFile f; CFileDialog fd(FALSE); if (fd.DoModal()==IDOK) { if (f.Open(fd.GetPathName(),CFile::modeCreate|CFile::modeWrite)) { f.Write(&nSize,sizeof(nSize)); for (int i=0;i<nSize;i++) f.Write(&pt[i],sizeof(pt[i])); f.Close(); } } } void CMyWin::OnPaint() { CDC *dc=GetDC(); RECT rt; GetClientRect(&rt); int gx = (rt.right-rt.left)/2; int gy = (rt.bottom-rt.top)/2; dc->MoveTo(gx,0); dc->LineTo(gx,2*gy); dc->MoveTo(0,gy); dc->LineTo(2*gx,gy); dc->MoveTo(gx-5,7); dc->LineTo(gx,0); dc->LineTo(gx+5,7); dc->MoveTo(2*gx-7,gy+5); dc->LineTo(2*gx,gy); dc->LineTo(2*gx-7,gy-5); for (int i=0;i<nSize;i++) dc->Ellipse(gx+pt[i].x-2,gy-pt[i].y-2,gx+pt[i].x+2,gy-pt[i].y+2); } void CMyWin::OnLButtonDown(UINT nFlags,CPoint pt) { RECT rt; GetClientRect(&rt);

259

int gx = (rt.right-rt.left)/2; int gy = (rt.bottom-rt.top)/2; if (nSize >= MAXPOINT) return; this->pt[nSize].x=pt.x-gx; this->pt[nSize].y=gy-pt.y; nSize++; CDC *dc=GetDC(); dc->Ellipse(pt.x-2,pt.y-2,pt.x+2,pt.y+2); }

Chng trnh vit di dng ca s bnh thng (khng dng kin trc ti liu/quan st). Thc hin ghi tp v c tp trong hai chc nng ng vi hai hm OnOpen() v OnSave() ca lp ca s CMyWin. Trong hai hm ny c s dng i tng lp CStdioFile thc hin c ghi tp, trc dng i tng lp CFileDialog m hp thoi chn tn tp cn lu gi hoc cn m. xc nh hp thoi l m hay ghi ta a vo tham s ca hm to lp CFileDialog gi tr tng ng l TRUE hay FALSE, nh v d trn. Kt qu chng trnh l:

260

8.2. C ch xut d liu ra my in trn Windows


xut d liu ra cc thit b nh mn hnh, my in chng ta phi s dng ng cnh thit b ca mn hnh hay my in tng ng. Cng ging nh mn hnh c trnh by chng trc, xut d liu ra my in thng qua ng cnh my in. Trc khi mun in chng ta phi xc nh ng cnh my in, c th dng hm CreateDC() to ng cnh thit b my in thc hin theo mu sau:
BOOL CDC :: CreateDC( LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const void* lpInitData );

Trong lpszDriverName l tn trnh iu khin thit b my in, lpszDeviceName l tn thit b my in, lpszOutput l tn tp nu cn v lpInitData l d liu khi to. Tuy nhin ngi lp trnh s khng mun phi xc nh cc tham s trn, ph thuc vo s ci t trong h iu hnh chn ra cc my ty theo ngi dng. lm iu ny chng ta s dng i tng lp hp thoi my in CPrintDialog. Lp ny c cc hm thnh vin nh sau: - Hm to i tng
CPrintDialog :: CPrintDialog( BOOL bSO, ... );

Hm c kh nhiu tham s v hu ht c t mc nh, tham s u c gi tr TRUE nu ch thit lp my in, v FALSE c th chn my in in d liu. Sau khi to xong i tng my in bn c th gi hm DoModal() hin hp thoi my in cho ngi dng la chn, hoc chn mc nh nh hm sau. - Xc nh my in mc nh ang chn trong h thng
BOOL GetDefaults( );

Hm tr v gi tr TRUE nu c my in ang chn trong h thng v ngc li FALSE nu khng c my in.


261

- Xc nh ng cnh my in la chn
HDC GetPrinterDC( ) const;

Hm tr v gi tr kiu HDC l ng cnh my in c chn bi ngi dng qua hp thoi hoc ly mc nh. Sau khi xc nh c ng cnh my in qua i tng lp CPrintDialog chng ta gn n vo mt i tng lp CDC thc hin xut d liu, lnh gn nh sau:
BOOL CDC :: Attach( HDC hDC );

V d xc nh ng cnh my in nh sau:
CDC dc; CPrintDialog pd(FALSE); if (pd.DoModal() == IDOK) { dc.Attach( pd.GetPrinterDC() ); ... th c hi n xu t d li u ra my in t i y ... }

Cc thao tc xut d liu ra my in u thc hin qua i tng lp CDC c gn vi ng cnh my in nh trn. Cng ging nh xut d liu ra ca s qua DC, chng ta c th s dng cc hm thnh vin xut d liu nh vn bn, cc lnh v,... Chng ta thy mt qu trnh in c th rt nhiu trang, do trong qu trnh xut d liu ra my in chng ta thc hin cc bc nh sau: Bc 1: Bt u in bng cch gi hm StartDoc() theo mu sau:
int CDC :: StartDoc( LPDOCINFO lpDocInfo );

Trong tham s lpDocInfo l cu trc DOCINFO lu cc thng tin lin quan n my in ang chn tng ng, cu trc DOCINFO gm cc thnh phn c khai bo nh sau:
typedef struct { int cbSize; LPCTSTR lpszDocName;

262

LPCTSTR lpszOutput; LPCTSTR lpszDatatype; DWORD fwType; DOCINFO, *LPDOCINFO;

Thnh phn cbSize lu ln ca cu trc, lpszDocName l tn ti liu cho qu trnh in , lpszOutput l tn tp nu xut ra tp thng bng NULL, hai thnh phn sau khng s dng l lpszDatattype t bng NULL v fwType t bng 0. Hm StartDoc() tr v kt qu thnh cng ng vi mt s dng l s hiu cng vic ang thc hin trong h thng, ngc li tr v gi tr 0 hoc m. Bc 2: Bt u in mt trang bng cch gi hm StartPage() theo mu sau:
int StartPage( );

Bc 3: Thc hin cc lnh xut d liu nh vn bn, cc lnh v,... Bt u mi trang in chng ta cn phi thit lp cc ch xut d liu nu cn nh mu sc, t nn nh trn ca s, s dng cc i tng lp CPen, CBrush,... v thit lp ch nh x n v v SetMapMode(),... Bc 4: Kt thc trang in bng lnh sau:
int EndPage( );

Bc 5: Nu cn d liu th lp li bc 2 in mt trang mi, nu khng sang bc 6. Bc 6: Kt thc mt qu trnh in bng lnh sau:
int EndDoc( );

Hai hm EndPage() v EndDoc() s tr v kt qu in, bao gm cc gi tr vi ngha nh sau:


Gi tr SP_ERROR SP_OUTOFDISK SP_OUTOFMEMORY SP_USERABORT ngha L i in Trn a

Trang b nh RAM my tnh K t thc b i l a ch n ng i dng

263

V d 8.2
Lp trnh v mt elp ln ca s v cho php in ra khi chn chc nng trn thc n. in ra trn giy c kch thc theo quy nh ta s dng ch nh x l MM_LOMETRIC theo t l mt n v v tng ng vi 0,1 mm. Vy 100 n v lgc ng vi 1 cm. Ni dung chng trnh l:
#include<afxwin.h> #include<afxdlgs.h> #define ID_PRINT 174 #define ID_DRAW 142 #define ID_EXIT 149 /* Khai bo l p ng d ng */ class CMyApp : public CWinApp { public: BOOL InitInstance(); }; /* Khai bo l p khung c a s ng d ng */ class CMyWin : public CFrameWnd { public: CMyWin(); void OnPrint(); void OnDraw(); void OnExit(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_COMMAND(ID_PRINT,OnPrint) ON_COMMAND(ID_DRAW,OnDraw) ON_COMMAND(ID_EXIT,OnExit) END_MESSAGE_MAP() BOOL CMyApp::InitInstance()

264

{ m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 02 - Chuong 08"); CMenu mn; mn.CreateMenu(); mn.AppendMenu(MF_BYCOMMAND|MF_STRING,ID_DRAW,"Draw"); mn.AppendMenu(MF_BYCOMMAND|MF_STRING,ID_PRINT,"Print"); mn.AppendMenu(MF_BYCOMMAND|MF_STRING,ID_EXIT,"Exit"); SetMenu(&mn); } void CMyWin::OnPrint() { CDC dc; CPen p; p.CreatePen(PS_SOLID,3,RGB(255,0,0)); CPrintDialog pd(FALSE); DOCINFO di; pd.DoModal(); dc.Attach(pd.GetPrinterDC()); di.cbSize=sizeof(di); di.fwType=0; di.lpszDatatype=NULL; di.lpszOutput=NULL; di.lpszDocName="Tai lieu in thu"; dc.StartDoc(&di); dc.StartPage(); dc.SelectObject(&p); dc.SetMapMode(MM_LOMETRIC); dc.Ellipse(0,0,1000,-1000); dc.EndPage(); dc.EndDoc(); MessageBox("Da in xong !"); dc.DeleteDC(); } void CMyWin::OnDraw()

265

{ CPen p; p.CreatePen(PS_SOLID,3,RGB(255,0,0)); CDC *dc=GetDC(); dc->SelectObject(&p); dc->SetMapMode(MM_LOMETRIC); dc->Ellipse(0,0,1000,-1000); } void CMyWin::OnExit() { DestroyWindow(); }

Trong hm OnPrint() trn chng ta s dng mt i tng hp thoi my in (CPrintDialog), sau s dng hm DoModal() hin ln mn hnh mt hp thoi my in cho php ngi dng chn mt my in ci t trong h thng. Hm GetPrinterDC() s tr v ng cnh thit b my in c chn. Kt qu chng trnh khi chn chc nng Draw l:

266

Khi chn chc nng Print s xut hin hp thoi my in:

Chn my in xong v bm chc nng Print trn hp thoi th lnh DoModal() s tr v gi tr IDOK v thc hin in. Qu trnh in thc hin bn trong cp lnh StartDoc() v EndDoc(), mi trang in thc hin bn trong cp lnh StartPage() v EndPage(). Chng ta s dng cc hm trong lp CDC in d liu ra my in nh vic hin ln ca s. Trong v d trn ch dng lnh Ellipse() v mt hnh trn c mu . Trong ca s my in chng ta c mt ti liu ang in:

267

8.3. Cch in ti liu trong MFC


Th vin MFC cung cp cc tin trnh in n gin hn, cc thao tc phn trn c gi trong cc lp ca th vin. c bit trong ng dng kiu ti liu/quan st th mi thao tc ny u t ng lm v ngi lp trnh ch thc hin ging nh vi mn hnh. Trong khung ng dng s t ng cp pht DC my in cho ngi lp trnh, sau t gii phng khi in xong. Cc thao tc bt u - StartDoc() v kt thc - EndDoc() tin trnh in, bt u StartPage() v kt thc EndPage() mt trang in cng c t ng gi thc hin. Ngoi ra cung cp mt hm thc hin hy b tin trnh do ngi dng yu cu. Ngi lp trnh s dng tin trnh in qua c ch lm vic ca lp CView, mt s hm cn phi vit lp dn xut ca CView vi ngha nh sau:

8.3.1. Hm chun b cng tc in


BOOL CView :: OnPreparePrinting( CPrintInfo* pInfo );

Hm c gi ngay khi bt u in, vit hm ny chn my in, gi hm to ng cnh my in, cung cp cc thng tin v in nh s trang,... Tham s pInfo l con tr ti i tng lp CPrintInfo lu gi thng tin v my in v thng tin v tin trnh in. Trong phin bn vit hm OnPreparePrinting() bn phi gi hm DoPreparePrinting() hin hp thoi my in cho ngi dng la chn v thc hin to ng cnh my in nu chn xong. Hm c khai bo nh sau:
BOOL CView :: DoPreparePrinting( CPrintInfo* pInfo );

Hm tr v gi tr TRUE nu thc hin thnh cng v ngc li l gi tr FALSE. Kt qu hm ny cng l kt qu hm OnPreparePrinting() trn. Ngoi ra chng ta c th thit lp cc thng tin v tin trnh qua tham s pInfo ca lp CPrintInfo, bao gm:
void void CView :: SetMinPage( UINT nMinPage ); CView :: SetMaxPage( UINT nMaxPage );

268

Hm quy nh s ca trang in u tin v s ca trang in cui cng vi tham s tng ng l nMinPage hay nMaxPage. Hoc ngc li chng ta c hm GetMinPage() v GetMaxPage() tr v hai gi tr tng ng. Nh vy s trang in ra s l nMaxPage - nMinPage + 1. Lp CPrintInfo cha thnh phn m_strPageDesc m t nh dng s trang c in ra gm mt xu k t cha hai xu con, xu con th nht m t cho hin th trang n v xu con th hai m t hin th trang i, hai xu cch nhau du '\n'. Mc nh l Page %u\nPages %u-%u\n, tuy nhin bn c th quy nh li nh dng khc v thc hin iu ny trong hm vit OnPreparePrinting(). V d v phin bn vit nh sau:
BOOL CMyView :: OnPreparePrinting(CPrintInfo* pInfo) { pInfo->SetMinPage(1); pInfo->SetMaxPage(5); return DoPreparePrinting(pInfo); }

8.3.2. Hm bt u in v kt thc in
Nh chng ta bit trc mt tin trnh in chng ta phi thit lp cc ch cho ng cnh my in nh xc nh tng s trang in ra da vo ln ca ti liu in, to co ch nu cn thit,... Trong phin bn ca lp dn xut t CView chng ta vit hm OnBeginPrinting() thc hin cc cng vic trn v ngc li hm OnEndPrinting() gii phng cc ti nguyn to ra. Hm bt u v kt thc in c khai bo theo mu sau:
void void CView :: OnBeginPrinting( CDC* pDC, CPrintInfo* pInfo ); CView :: OnEndPrinting( CDC* pDC, CPrintInfo* pInfo );

Tham s pDC tr n i tng lp CDC biu din ng cnh ca my in, pInfo tr n i tng lp CPrintInfo c s dng hm chun b in trn. Trong hm chun b in chng ta c thit lp s trang in nhng khi cha xc nh c tng s trang in ra, tham s ny ph thuc vo di ca ti
269

liu v kch thc vng in ra. Do c th thc hin trong hm bt u in OnBeginPrinting() nh sau: Bc 1: Xc nh cao ca vng in c qua lp CDC
int CDC :: GetDeviceCaps( int nIndex ) const;

Tham s nIndex quy nh chiu v n v xc nh ln, thng thng chng ta t l VERTSIZE hoc HORZSIZE ly chiu cao hoc chiu rng theo n v milimet. Bc 2: Xc nh di ca ti liu, da vo hm GetDocument() tr v ti liu xc nh ln ca ti liu do chng trnh chng ta to v x l. Bn nn to mt hm thnh vin trong lp ti liu xc nh di ca ti liu theo mt n v no . Bc 3: Tnh t s di ti liu/ cao ca vng in ta c s trang, tuy nhin hai gi tr t s trn phi cng n v mi chnh xc, c th l milimet. Bc 4: Dng hai hm SetMinPage() v SetMaxPage() thit lp s trang in ra cho i tng lp CPrintInfo qua tham s pInfo. Ngoi ra chng ta c th tnh ton v to co ca ch in ra trong trng hp in vn bn cng c thc hin trong hm ny. Ni chung lp CView cung cp hai hm ny OnBeginPrinting() v OnEndPrinting() cho php ngi lp trnh thc hin cc cng vic bt u v kt thc in cho mt qu trnh xut d liu ra my in. Nu khng bn khng cn phi vit hai hm ny trong phin bn lp dn xut ca CView.

8.3.3. Hm chun b ng cnh cho mt trang in


Nh trnh by trc mi mt trang in ra chng ta phi thc hin thit lp cc ch cho ng cnh thit b my in, MFC cung cp hm OnPrepareDC() trong lp CView thc hin iu ny. Hm ny s c gi mi ln in mt trang ti liu. Hm c khai bo nh sau:
void CView :: OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL );

270

Hm ny cn c gi trong trng hp xut d liu ra mn hnh, khi pDC tr n i tng lp CDC biu din ng cnh mn hnh v gi tr pInfo bng NULL. bit tham s pDC ca hm ny ang biu din cho ng cnh my in hay khng ta s dng hm CDC :: IsPringting() tr v gi tr khc 0 l my in, nu bng 0 th ng cnh tng ng l ca mn hnh. Cc thao tc thng thc hin trong hm ny l: - Quy nh gc ca khung nhn trong vng in ra s dng hm SetViewportOrg(). - To vng ct gii hn vng in ra so vi ban u ca my in dng hm CDC::SelectClipRgn() vi tham s l i tng lp CRgn xc nh vng gii hn cn t. - t ch nh x n v lgc trn ng cnh thit b my in bng hm SetMapMode(). Ch : Trong phin bn vit hm ny chng ta lun phi gi hm c s tng ng CView::OnPrepareDC() lnh u tin.

8.3.4. Hm thc hin in


Sau khi hm OnPrepareDC() c thc hin xong, khung ng dng s gi hm OnPrint() kim tra tnh hp l ca ng cnh my in v chuyn qua li gi hm OnDraw(). Hm OnPrint() c khai bo nh sau:
void CView :: OnPrint( CDC* pDC, CPrintInfo* pInfo );

Thc cht qu trnh xut d liu ra my in c thc hin chnh thc trong hm OnDraw() theo tng trang mt, cn hm OnPrint() nu cn vit trong phin bn lp dn xut thc hin in ra cc tiu trang, in ra s trang,... l nhng phn m trong hm OnDraw() khng c thc hin. Nu m lnh cho vic xut d liu ra my in v mn hnh khc nhau th trong phin bn np chng hm OnPrint() chng ta thc hin lun cc thao tc m khng gi n hm OnDraw().

271

Trong tham s pInfo tr ti i tng lp CPrintInfo c thnh vin d liu m_nCurPage xc nh s trang ang in hin thi, do trong hm OnPrint() chng ta s dng gi tr ny bit ni dung cn in ra trn trang tng ng. Ch : Nu c thay i ca ng cnh my in bi hm SetViewportOrg() hoc SelectClipRgn() th nn thc hin trong hm OnPrint() cc tiu v s trang in ra khng b tc ng.

8.3.5. Hm nh x thng ip in chun ID_FILE_PRINT


MFC cung cp mt hm nh x cho thng ip in chun l hm CView::OnFilePrint(). Trong chng trnh chng ta c th s dng s hiu ID_FILE_PRINT ny to mt chc nng in v nh x ti hm tng ng hoc ti hm c vit . S qu trnh in trong MFC c th minh ha nh sau:

272

8.3.6. Quan st trc khi in


Hu ht cc ng dng trn Windows cho php ngi s dng xem xt b cc v ni dung trang trc khi xut ra my in. Cng vic ny c thc hin thng qua hm thnh vin OnFilePrintPreview ca lp CView. Trong hm ny s gi n hm DoPrintPreview hin th ca s xem trang in. Phin bn lp dn xut t lp CView bn phi nh x x l thng ip ID_FILE_PRINT_PREVIEW v gi hm OnFilePrintPreview ca lp CView thc hin xem trang in. Tham s i tng lp CPrintInfo c thnh vin m_bPreview c gi tr TRUE tin trnh in c xem trc (thc hin hm DoPrintPreview) v ngc li FALSE. Thnh vin m_nNumPreviewPages lu s trang cng xem mt lc trn ca s ny. Ch : Trong chng trnh kiu ti liu/quan st c s dng c ch in ca MFC chng ta phi thit lp ch s dng cc lp th vin MFC dng chia s. Cc bc chn l Project Setting (Alt+F7) trong th General chn gi tr "Use MFC in shared DLL" trong mc "Microsoft Foundation Class".

V d 8.3
Lp trnh thc hin v ln mn hnh bn c Car, cho php bm chut in cc du X hoc O lun phin nhau, c th xem v in trang bn c ra giy bng chc nng trn thc n. Lp CMyDoc dn xut t lp CDocument s lu cc thng tin v trng thi bn c. Lp CMyView lm cc nhim v chnh nh nh x x l thng ip chc nng, bm chut v nh du vo c,... Tp nh ngha hng ti nguyn resource.h
#define IDR_MYWIN #define ID_FILE_RESET #define ID_FILE_EXIT #define MAXSIZE 101 40001 40004 30

Tp khai bo ti nguyn main.rc


#include "resource.h" #include "afxres.h"

273

// Menu IDR_MYWIN MENU DISCARDABLE BEGIN POPUP "File" BEGIN MENUITEM "Reset", ID_FILE_RESET MENUITEM "Print preview", ID_FILE_PRINT_PREVIEW MENUITEM "Print", ID_FILE_PRINT MENUITEM SEPARATOR MENUITEM "Exit", ID_FILE_EXIT END END // String Table STRINGTABLE DISCARDABLE BEGIN IDR_MYWIN "Chuong trinh Vidu03/Chuong8\nLHLK\nLHK Type (*.lhk)\n.lhk\n\nV3C8FT\nV3C8FN" END

Tp khai bo cc lp trong chng trnh main.h


class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { DECLARE_DYNCREATE(CMyWin); }; class CMyDoc : public CDocument { DECLARE_DYNCREATE(CMyDoc) public: char ttBanco[MAXSIZE][MAXSIZE]; char ttDau; void OnReset(); char OnDanhDau(int i,int j); BOOL OnNewDocument(); }; class CMyView : public CView

274

{ DECLARE_DYNCREATE(CMyView) public: CBitmap mBMP; CDC mDC; CBrush mBR; CPen mP; int XMAX,YMAX; int DauSize; BOOL IsPrint; afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); afx_msg void OnLButtonDown(UINT nFlags,CPoint pt); void OnExit(); void OnReset(); void OnDraw(CDC *dc); void OnDrawBanco(); BOOL OnPreparePrinting(CPrintInfo *pInfo); void OnPrint( CDC* pDC, CPrintInfo* pInfo ); DECLARE_MESSAGE_MAP() };

Tp ni dung m lnh chng trnh main.cpp


#include<afxwin.h> #include<afxext.h> #include"resource.h" #include"main.h" CMyApp theApp; IMPLEMENT_DYNCREATE(CMyDoc,CDocument) IMPLEMENT_DYNCREATE(CMyWin,CFrameWnd) IMPLEMENT_DYNCREATE(CMyView,CView) BEGIN_MESSAGE_MAP(CMyView,CView) ON_WM_CREATE() ON_WM_LBUTTONDOWN() ON_COMMAND(ID_FILE_EXIT,OnExit) ON_COMMAND(ID_FILE_RESET,OnReset) ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() {

275

CSingleDocTemplate *pd=new CSingleDocTemplate( IDR_MYWIN, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMyWin), RUNTIME_CLASS(CMyView)); AddDocTemplate(pd); EnableShellOpen(); RegisterShellFileTypes(); CCommandLineInfo cif; ParseCommandLine(cif); if (!ProcessShellCommand(cif)) return FALSE; return TRUE; } void CMyView::OnExit() { CWnd *w=GetParent(); w->DestroyWindow(); } void CMyView::OnDrawBanco() { int x,y,mi,mj,i,j,mx,my; mi=YMAX/DauSize; mj=XMAX/DauSize; mx=(mj-1)*DauSize; my=(mi-1)*DauSize; for (x=0,j=0;j<=mj;x+=DauSize,j++) { mDC.MoveTo(x,0); mDC.LineTo(x,my); } for (y=0,i=0;i<=mi;y+=DauSize,i++) { mDC.MoveTo(0,y); mDC.LineTo(mx,y); } } void CMyView::OnDraw(CDC *dc) { RECT rt; dc->GetClipBox(&rt); int cx=rt.right-rt.left, cy=rt.bottom-rt.top;

276

if (IsPrint) dc->StretchBlt(0,0,cx,cy,&mDC,0,0,XMAX,YMAX,SRCCOPY); else dc->BitBlt(0,0,cx,cy,&mDC,0,0,SRCCOPY); IsPrint=FALSE; } int CMyView::OnCreate( LPCREATESTRUCT lpCreateStruct ) { int kq=CView::OnCreate(lpCreateStruct); CClientDC dc(this); XMAX= GetSystemMetrics(SM_CXSCREEN); YMAX= GetSystemMetrics(SM_CYSCREEN); mBMP.CreateCompatibleBitmap(&dc,XMAX,YMAX); mDC.CreateCompatibleDC(&dc); mP.CreatePen(PS_SOLID,1,RGB(0,0,255)); mBR.CreateStockObject(WHITE_BRUSH); mDC.SelectObject(&mBMP); mDC.SelectObject(&mBR); mDC.SelectObject(&mP); mDC.PatBlt(0,0,XMAX,YMAX,PATCOPY); DauSize=20; IsPrint=FALSE; OnDrawBanco(); return kq; } void CMyView::OnLButtonDown(UINT nFlags,CPoint pt) { int i,j,x,y,x1,y1; char kq; CMyDoc *d = (CMyDoc*)GetDocument(); i=pt.y/DauSize; j=pt.x/DauSize; x=j*DauSize; y=i*DauSize; x1=x+DauSize; y1=y+DauSize; kq=d->OnDanhDau(i,j); if (kq==1) { mDC.MoveTo(x+3,y+3); mDC.LineTo(x1-3,y1-3); mDC.MoveTo(x1-3,y+3); mDC.LineTo(x+3,y1-3); } else if (kq==2)

277

{ mDC.Ellipse(x+3,y+3,x1-3,y1-3); } InvalidateRect(NULL); } void CMyView::OnReset() { mDC.PatBlt(0,0,XMAX,YMAX,PATCOPY); CMyDoc *d=(CMyDoc*)GetDocument(); d->OnReset(); OnDrawBanco(); InvalidateRect(NULL); } BOOL CMyView::OnPreparePrinting(CPrintInfo *pInfo) { pInfo->SetMaxPage(1); return DoPreparePrinting(pInfo); } void CMyView::OnPrint( CDC* pDC, CPrintInfo* pInfo ) { IsPrint=TRUE; CView::OnPrint(pDC,pInfo); } char CMyDoc::OnDanhDau(int i,int j) { if ((i<MAXSIZE)&&(j<MAXSIZE)&&(ttBanco[i][j]==0)) { ttBanco[i][j]=ttDau; if (ttDau==1) { ttDau=2; return 1;} else { ttDau=1; return 2; } } return 0; } BOOL CMyDoc::OnNewDocument() {

278

OnReset(); return CDocument::OnNewDocument(); } void CMyDoc::OnReset() { ::ZeroMemory(ttBanco,sizeof(char)*MAXSIZE*MAXSIZE); ttDau=1; }

Hm CMyView::OnExit() ly ra ca s cha khung nhn bng lnh GetParent() v gi hm DestroyWindow() thot khi chng trnh. Trong hm ny chng ta c th s dng i tng theApp xc nh ca s chnh bng lnh GetMainWnd() kt thc thay cho lnh GetParent(). Bn c c v trn mt ca s o c DC cha i tng mDC, l thnh vin lp CMyView. Cc thao tc v bn c v nh du mi khi ngi dng bm chut ln bn c u thc hin trn ca s o, sau trong hm OnDraw() s chp vo ca s bng lnh BitBlt(). Ngoi ra trong hm OnDraw() thc hin chp ca s o sang my in bng lnh StretchBlt() nu chng ta ang in da vo bin IsPrint c thit lp trong hm OnPrint(). Hm StretchBlt() c tc dng nh BitBlt(), chp hnh nh t mt DC vo mt DC khc (t ca s o vo DC my in) v thc hin co gin nh ngun c chng kht ln vng in c. Hm v bn c CMyView::OnDrawBanco() thc hin v cc ng thng dc v ngang vi khong cch nh nhau bng DauSize n v v lgc. Chng ta vit hm OnCreate() trong lp CMyView thc hin to mt ca s o cho lp khung nhn tng ng, t nn ca s o l nn trng quy nh bng mBR, mu v l mu xanh quy nh bng mP. mBR v mP l cc thnh vin ca lp CMyView. nh x x l thng ip nhn chut tri bi hm OnLButtonDown() trong lp CMyView xc nh ta chut khi nhn tnh ta c thc hin nh du nu ang cn trng. Sau thay i trng thi nh du da vo bin ttDau bng 1 l X v bng 2 l O. Kt qu chng trnh s l:

279

Nu chn chc nng "Print preview" s c mn hnh nh sau:

280

8.4. Bi tp
Bi tp 8.1
Lp trnh dng ca s n gin cho php in dng ch thng tin ca bn ra my in, gm h tn, ngy sinh, qu qun.

Bi tp 8.2
Lp trnh dng ca s n gin thc hin v ln mn hnh l c t quc, cho php in ra my in khi chn chc nng trn thc n.

Bi tp 8.3
Lp trnh dng ca s n gin kim tra tc g phm bng cch hin ra mt dng ch trn ca s. Ch g tng ch trong xu k t v kim tra chnh xc, sau tnh phn trm s ch g ng. Sau khi g xong hi ngi chi c in kt qu khng? nu c thc hin in ra my in thng tin v bn gm h tn, ngy sinh, xu k t kim tra, xu k t g vo, phn trm g ng.

Bi tp 8.4
Lp trnh kiu ti liu/quan st cho php nhp cc ch ci v ch s t bn phm hin ln ca s. C th chn phng ch v mu ch hin th (phi tnh co gin ch khng vt ra ngoi ca s). C th xem v in ra my in qua thc n.

Bi tp 8.5
Lp trnh kiu ti liu quan st v bn c vua ln ca s, to cc qun c vua trong ti nguyn bitmap v np vo chng trnh, cho php chn mt qun c trn thanh cng c v bm chut vo mt v qun c vo (chp nh bitmap vo). C th xem v in bn c sau khi v ra my in.

281

Chng 9 LP TRNH A TUYN


9.1. Cc khi nim c bn
Windows l mt h iu hnh a nhim nu nhn di gc ngi s dng. Tuy nhin di gc lp trnh th Windows cung cp hai c ch a nhim, th nht a nhim theo ch tin trnh (process) tc l ti mt thi im c th thc hin nhiu tin trnh (nhiu chng trnh cng thc hin), ch ny tn ti Window 3.11. Th hai a nhim theo ch lung (thread) c cung cp bi Win32, trong mt tin trnh c th cha nhiu lung v tt nhin s c ti thiu mt lung trong mi tin trnh gi l lung chnh (main thread). Vi cch th hai ny ngi lp trnh c th phn chia cng vic thnh nhiu lung x l khc nhau c lp tn dng ti a thi gian ca CPU v khng phi ch nhau khi thc hin. Lp trnh c phn chia v x l n cc lung ta gi l lp trnh a tuyn. Th vin MFC cung cp c ch lp trnh a tuyn kh hon thin v d dng i vi lp trnh vin. V d chng ta c th t chc chng trnh thnh 3 lung, lung th nht x l cng vic lu tr d liu ln a, lung th 2 ly thng tin t mt thit b t xa no , lung th 3 nhn v x l cc yu cu t ngi dng. Tin trnh l qu trnh thc hin mt chng trnh no , mi khi bt u mt tin trnh th mt lung chnh ng vi tin trnh cng c bt u thc hin v chng ta c th to thm nhiu lung mi t y. MFC nh ngha hai kiu lung: lung giao din (interface) v lung lm vic (worker). Lung giao din c th nhn v x l cc thng ip, n cha mt vng lp thu nhn v chuyn pht thng ip (message pump). Nh

282

chng ta thy trong cc v d trc mi chng trnh c lung chnh c bt u ti thi im to i tng lp CMyApp v n l mt lung giao din. Lung lm vic khng nhn v x l thng ip, thay v n cung cp thm mt lung x l cng vic no t lung giao din. C rt t chng trnh cn nhiu vng lp nhn v x l thng ip nn hu ht cc chng trnh ch c mt lung giao din tng ng l lung chnh. Thng thng chng ta to thm cc lung lm vic khc x l cc cng vic trong chng trnh v trong chng ny s v d v kiu lung ny. Ch : Trong lp trnh API hai kiu lung ny ch c xem nh mt, s phn chia ch c tc dng trong lp trnh MFC.

9.2. To v s dng lung


Th vin MFC cung cp c ch lp trnh a tuyn bi lp CWinThread v n l lp c s ca lp CWinApp, lp ng dng ny s hnh thnh lung giao din v l lung chnh trong chng trnh.

9.2.1. To lung lm vic


to mt lung lm vic s dng hm AfxBeginThread() c hai mu khai bo nh sau:
CWinThread* AfxBeginThread( AFX_THREADPROC LPVOID pParam, int Priority = THREAD_PRIORITY_NORMAL, UINT StackSize = 0, DWORD CreateFlag = 0, LPSECURITY_ATTRIBUTES SecAttr = NULL ); ThreadProc,

Mi lung c bt u bng cch gi mt hm, hm ny gi l hm lung. Qu trnh thc hin lung s tip tc cho n khi hm ca lung kt thc. Tham s ThreadProc l a ch ca hm ny v hm phi c khai bo theo mu sau:
UINT ThreadProc( LPVOID pParam ); 283

Gi tr pParam ca hm AfxBeginThread() s c chuyn vo tham s pParam ca hm lung trn. Chng ta s dng tham s ny cho mi mc ch. Tham s Priority quy nh mc u tin ca lung i vi ti nguyn thi gian CPU, mc nh l ch u tin bnh thng. Tuy nhin c th s dng mt trong cc gi tr sau:
Gi tr THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_HIGHEST THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_NORMAL THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_LOWEST THREAD_PRIORITY_IDLE ngha i h i th i gian tuy t i u tin cao nh t Trn m c bnh th ng Bnh th ng D i m c bnh th ng Th p nh t Nhn r i

Mi lung c mt stack ca bn thn n cha cc thng tin v qu trnh thc hin. Chng ta c th t kch thc cho stack ca lung qua tham s StackSize, nu khng my s ly mc nh l bng vi stack ca lung to ra n. Tham s CreateFlag quy nh trng thi thc hin ca lung. Mc nh bng 0 th lung s c thc hin ngay sau khi to, nu t bng CREATE_SUSPENDED th lung to ra s cha thc hin ngay, s ch cho n khi gi hm CWinThread::ResumeThread(). Con tr SecAttr s tr n cu trc cc thuc tnh quy nh an ton i vi lung c to ra, thng ly mc nh bng NULL s t ng ly cc thuc tnh t lung hin ti t cho lung mi. Cu trc ny c khai bo l:
typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; *PSECURITY_ATTRIBUTES

} SECURITY_ATTRIBUTES,

284

Hm AfxBeginThread() tr v mt con tr ti i tng ng vi lung c to ra hoc tr v 0 nu b li. Nu bn cn truy xut thay i thuc tnh an ton hoc trng thi lm vic th cn phi lu gi con tr ny, thng thng b qua kt qu ny. Ngoi ra hm to lung c dng th hai nh sau:
CWinThread* AfxBeginThread( CRuntimeClass* int ThreadClass,

Priority = THREAD_PRIORITY_NORMAL, StackSize = 0, CreateFlag = 0,

UINT

DWORD

LPSECURITY_ATTRIBUTES SecAttr = NULL );

Thay tham s tn hm ca lung bng con tr lp dn xut t CWinThread, s dng c ch lp ng thng qua macro RUNTIME_CLASS() truyn cho tham s ny. Hm ca lung hoc lp ny s thc hin cc cng vic ng vi lung c to ra.

9.2.2. Kt thc mt lung


Nh chng ta thy trn, thi im kt thc mt lung l lc kt thc hm x l ca lung . Tuy nhin c th kt thc ti thi im ty trong qu trnh thc hin bng cch gi hm sau:
void AfxEndThread( UINT nExitCode );

Trong nExitCode l trng thi kt thc. Thng thng chng ta lung kt thc khi hm tng ng ca n kt thc.

V d 9.1
Lp trnh to mt lung lm vic khi chn chc nng trn thc n. Hm ca lung thc hin in ln mn hnh mt thng bo v to ting bp. Hm x l lung s nhn d liu qua tham s kiu LPVOID l mt con tr ti i tng lp ca s, t xc nh ng cnh hin th d liu. Ni dung tp chng trnh l:
285

#include<afxwin.h> #define IDM_THREAD 174 #define IDM_EXIT 142 UINT MyThread(LPVOID pMain); int MyID=0; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: int mY; CMyWin(); void OnThread(); void OnExit(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_COMMAND(IDM_THREAD,OnThread) ON_COMMAND(IDM_EXIT,OnExit) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 01 - Chuong 9"); CMenu mn; mn.CreateMenu(); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_THREAD,"Thread"); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_EXIT,"Exit"); SetMenu(&mn); mY=0; } void CMyWin::OnThread()

286

{ AfxBeginThread(MyThread,this); } void CMyWin::OnExit() { DestroyWindow(); } UINT MyThread(LPVOID pMain) { CMyWin *p = (CMyWin*)pMain; CDC *d = p->GetDC(); char s[255]; int id = MyID++; TEXTMETRIC tm; d->GetTextMetrics(&tm); for (int i=0;i<60;i++) { Sleep(1000); sprintf(s,"(Thread=%d,Count=%d)",id,i); d->TextOut(id*150,p->mY,s,strlen(s)); p->mY=p->mY+tm.tmHeight+tm.tmExternalLeading; MessageBeep(MB_OK); } MyID--; return 0; }

Chng ta s dng mt bin ton cc MyID xc nh s hiu ca mt lung c to mi, bt u hm ca lung s tng MyID v thc hin cc vic, trc khi kt thc hm gim MyID kt thc lung . Hm ca lung c tham s truyn vo l con tr this (tr n i tng ca s chnh ca lp CMyWin) qua lnh AfxBeginMessage(), v th trong hm ny ta s dng tham s xc nh ng cnh ca s hin cc thng bo ca lung. Cng vic thc hin trong hm ca lung l mt lnh lp for gm 60 ln lp, mi ln s ch 1 giy (1000 mili giy) bng lnh Sleep(1000), hin thng bo s hiu ca lung v s ln ang lp, sau pht ting ku ra loa bng lnh MessageBeep(). Ni dung chng trnh sau khi chn to cc lung l:

287

V d 9.2
Lp trnh to hai lung lm vic, mt lung v qu bng mu chuyn ng trn ca s, mt lung v hnh vung mu xanh cho xut hin ti nhng v tr bt k. Nu qu bng gp cnh ca s s phn x tr li theo gc i xng. Trn mi qu bng v ra lung th nht c hin th s hiu qu bng tng ng vi ln to th my v tng t lung to hnh vung. Hai lung ny khng kt thc cho n khi kt thc chng trnh. x l tnh hung phn x ca qu bng chng ta xc nh ta ca n, nu gp mt cnh ca s s thay i bc tng dx theo x hoc dy theo y bng cch i du.
288

Ni dung chng trnh l:


#include<afxwin.h> #define IDM_THREAD1 174 #define IDM_THREAD2 147 #define IDM_EXIT 142 UINT MyThread1(LPVOID pMain); int MyID1 = 0; UINT MyThread2(LPVOID pMain); int MyID2 = 0; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); void OnThread1(); void OnThread2(); void OnExit(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_COMMAND(IDM_THREAD1,OnThread1) ON_COMMAND(IDM_THREAD2,OnThread2) ON_COMMAND(IDM_EXIT,OnExit) END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 02 - Chuong 9"); CMenu mn;

289

mn.CreateMenu(); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_THREAD1,"Bong do"); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_THREAD2,"Hinh vuong xanh"); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_EXIT,"Exit"); SetMenu(&mn); } void CMyWin::OnThread1() { AfxBeginThread(MyThread1,this); } void CMyWin::OnThread2() { AfxBeginThread(MyThread2,this); } void CMyWin::OnExit() { DestroyWindow(); } UINT MyThread1(LPVOID pMain) { CMyWin *p = (CMyWin*)pMain; CDC *dc = p->GetDC(); int r=15, id = MyID1++; //Tao mot ngu canh ao chua bong CDC mDC; CBitmap mBMP; CBrush mBR; char s[50]; mDC.CreateCompatibleDC(dc); mBMP.CreateCompatibleBitmap(dc,2*r,2*r); mBR.CreateStockObject(WHITE_BRUSH); mDC.SelectObject(&mBMP); mDC.SelectObject(&mBR); mDC.PatBlt(0,0,2*r,2*r,PATCOPY); mBR.DeleteObject(); mBR.CreateSolidBrush(RGB(255,0,0)); mDC.SelectObject(&mBR); CPen pen; pen.CreatePen(PS_SOLID,1,RGB(255,0,0)); mDC.SelectObject(&pen); mDC.Ellipse(1,1,2*r-1,2*r-1); sprintf(s,"%d",id); mDC.SetBkMode(TRANSPARENT); mDC.SetTextColor(RGB(0,255,0));

290

mDC.SetTextAlign(TA_CENTER); mDC.TextOut(r,r-8,s,strlen(s)); RECT rt; p->GetClientRect(&rt); int mx=rt.right-rt.left, my=rt.bottom-rt.top; int x,y,dx=1,dy=1; x=rand()*(id+7)%mx; y=rand()*(id+15)%my; while (1) { dc->BitBlt(x-r,y-r,2*r,2*r,&mDC,0,0,SRCCOPY); Sleep(10); dc->BitBlt(x-r,y-r,2*r,2*r,NULL,0,0,WHITENESS); x+=dx; if ((x<0)||(x>mx)) { dx=-dx; x+=dx; } y+=dy; if ((y<0)||(y>my)) { dy=-dy; y+=dy; } } pen.DeleteObject(); mDC.DeleteDC(); mBMP.DeleteObject(); mBR.DeleteObject(); MyID1--; return 0; } UINT MyThread2(LPVOID pMain) { CMyWin *p = (CMyWin*)pMain; CDC *dc = p->GetDC(); int r=10, id = MyID2++; //Tao mot ngu canh ao chua hinh vuong CDC mDC; CBitmap mBMP; CBrush mBR; char s[50]; mDC.CreateCompatibleDC(dc); mBMP.CreateCompatibleBitmap(dc,2*r,2*r); mBR.CreateStockObject(WHITE_BRUSH); mDC.SelectObject(&mBMP); mDC.SelectObject(&mBR); mDC.PatBlt(0,0,2*r,2*r,PATCOPY);

291

mBR.DeleteObject(); mBR.CreateSolidBrush(RGB(0,0,255)); mDC.SelectObject(&mBR); CPen pen; pen.CreatePen(PS_SOLID,1,RGB(0,0,255)); mDC.SelectObject(&pen); mDC.Rectangle(1,1,2*r-1,2*r-1); sprintf(s,"%d",id); mDC.SetBkMode(TRANSPARENT); mDC.SetTextColor(RGB(255,255,0)); mDC.SetTextAlign(TA_CENTER); mDC.TextOut(r,r-7,s,strlen(s)); RECT rt; p->GetClientRect(&rt); int mx=rt.right-rt.left, my=rt.bottom-rt.top; int x,y; x=(rand()*(id+5))%mx; y=(rand()*(id+5))%my; while (1) { dc->BitBlt(x-r,y-r,2*r,2*r,&mDC,0,0,SRCCOPY); Sleep(1000); dc->BitBlt(x-r,y-r,2*r,2*r,NULL,0,0,WHITENESS); x=(rand()*(id+5))%mx; y=(rand()*(id+5))%my; } pen.DeleteObject(); mDC.DeleteDC(); mBMP.DeleteObject(); mBR.DeleteObject(); MyID2--; return 0; }

Trong hai hm ca lung MyThread1() v MyThread2() u v hnh ln mt DC o, sau thc hin chp DC vo ca s tng v tr chuyn ng hoc ngu nhin. Kt qu chng trnh sau khi chn to mt s hnh trn v hnh vung nh sau:

292

9.3. Qun l lung


9.3.1. Dng v kch hot lung
Mt lung c th b tm dng thc hin bng vic gi hm SuspendThread(), khi lung s b ngng tr khng thc hin v n c kch hot li bng hm ResumeThread(). Hai hm c khai bo nh sau:
DWORD DWORD CWinThread :: SuspendThread( ); CWinThread :: ResumeThread( );

Mi lung thc hin s c mt gi tr m s ln tm dng. Nu gi tr ny bng 0 th lung tng ng ang hot ng, ngc li gi tr m khc 0 th lung ang trng thi dng. Mi ln gi hm SuspendThread() th gi tr ny s tng ln mt, ngc li mi ln gi hm ResumeThread() s gim i mt. Nh vy s ln gi hai hm phi bng nhau lung quay tr li trng thi hat ng. C hai hm trn u tr v gi tr m trc hoc bng -1 nu b li.
293

9.3.2. Qun l u tin lung


Mi lung to ra c gn vi n mt u tin (priority), u tin ny l s kt hp gia hai gi tr: gi tr u tin ca lp ng vi tin trnh process (lp ng dng - CMyApp) v gi tr u tin ca ring bn thn lung . u tin ca mt lung quy nh ti nguyn thi gian CPU dnh cho vic thc hin lung . Lung u tin thp s c t thi gian thc hin, lung u tin cao s c nhiu thi gian hn. Tt nhin thi gian CPU dnh cho mt lung s gp phi s va chm trn c tnh thc hin v s tng tc gia lung vi cc lung khc ang cng thc hin trong h thng. Chng ta c th xc nh u tin hin ti ca lp ng dng bng hm sau:
DWORD GetPriorityClass( HANDLE hProcess );

Trong tham s hProcess l s hiu ca tin trnh ang thc hin, tng ng vi lp ng dng CMyApp. Tham s ny chnh l gi tr HINSTANCE ca tin trnh, c ly t thnh vin ca i tng ng dng CWinApp::m_hInstance hoc s dng hm AfxGetInstanceHandle( ). t u tin cho tin trnh hin ti ta s dng hm sau:
BOOL SetPriorityClass( HANDLE DWORD hProcess, dwPriorityClass );

Trong hProcess l s hiu ca tin trnh hin ti cn t, dwPriorityClass l u tin cn t, bao gm cc gi tr sau:
Gi tr ABOVE_NORMAL_PRIORITY_CLASS BELOW_NORMAL_PRIORITY_CLASS HIGH_ PRIORITY_CLASS IDLE_ PRIORITY_CLASS NORMAL_ PRIORITY_CLASS REALTIME_ PRIORITY_CLASS ngha Trn m c bnh th ng D i m c bnh th ng u tin cao u tin th p u tin bnh th ng M c u tin cao nh t

Mc nh mi chng trnh u c mc u tin NORMAL_PRIORITY_CLASS. Thng thng bn khng cn phi t li mc u tin cho lp ng dng ca chng trnh, bi v s lm thay i qu trnh ang thc hin trn ton b h thng. Nu bn t u tin l cao
294

nht (REALTIME_PRIORITY_CLASS) th n s chi phi ti nguyn CPU. Ch c mt s t cc chng trnh c bit mi thc hin iu ny, do vy y chng ta nn s dng mc u tin mc nh. Vi mi mc u tin ca lp ng dng, mc u tin ca lung quy nh thi gian ca CPU dnh ring cho tng lung bn trong tin trnh tng ng. Khi to mt lung th s l u tin mc nh nhng chng ta c th thay i chng, thm ch ngay c khi n ang thc hin. Mc u tin lung c iu khin bi cc hm thnh vin lp CWinThread. Chng ta s dng hm GetThreadPriority() xc nh v SetThreadPriority() t mc u tin cho lung, hai hm c khai bo nh sau:
int BOOL CWinThread :: GetThreadPriority( ); CWinThread :: SetThreadPriority( int nPriority );

Hm GetThreadPriority() tr v gi tr u tin hin thi ca lung, tham s nPriority trong hm SetThreadPriority() quy nh mc u tin cn t, n bao gm cc gi tr sau sp xp t cao xung thp:
THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_HIGHEST THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_NORMAL THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_LOWEST THREAD_PRIORITY_IDLE

V d 9.3
Lp trnh to hai lung v t u tin khc nhau, xem xt s hat ng thc hin ca hai lung . Mi lung s thc hin m v hin ra gi tr m t 0 n 5000. Ni dung chng trnh l:

295

#include<afxwin.h> #define IDM_THREAD 174 #define IDM_EXIT 142 UINT MyThread1(LPVOID pMain); UINT MyThread2(LPVOID pMain); CWinThread *pThread1,*pThread2; int ttOnThread=0; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); afx_msg void OnTimer(UINT nIDEnvent); void OnThread(); void OnExit(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_COMMAND(IDM_THREAD,OnThread) ON_COMMAND(IDM_EXIT,OnExit) ON_WM_TIMER() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Vi du 03 - Chuong 9"); CMenu mn; mn.CreateMenu(); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_THREAD,"Bat dau");

296

mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_EXIT,"Exit"); SetMenu(&mn); } void CMyWin::OnTimer(UINT nIDEnvent) { CDC *dc=GetDC(); char s[100]; sprintf(s,"%2d",ttOnThread++); dc->TextOut(50,5,s,strlen(s)); } void CMyWin::OnThread() { if (ttOnThread>0) return; SetTimer(1,1000,NULL); ttOnThread=1; pThread1=AfxBeginThread(MyThread1,this); pThread2=AfxBeginThread(MyThread2,this); pThread1->SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL); pThread2->SetThreadPriority(THREAD_PRIORITY_IDLE); } void CMyWin::OnExit() { KillTimer(1); DestroyWindow(); } UINT MyThread1(LPVOID pMain) { CMyWin *p = (CMyWin*)pMain; CDC *dc = p->GetDC(); long Count1=0; char s[100]; while (Count1<5000) { for (long j=1,i=0;i<1000000;i++) j=i-j+2*i-3*j; sprintf(s,"{Count of Thread1 =%ld}",Count1++); dc->TextOut(0,50,s,strlen(s)); } return 0; } UINT MyThread2(LPVOID pMain) {

297

CMyWin *p = (CMyWin*)pMain; CDC *dc = p->GetDC(); long Count2=0; char s[100]; while (Count2<5000) { for (long j=1,i=0;i<1000000;i++) j=i-j+2*i-3*j; sprintf(s,"{Count of Thread2 =%ld}",Count2++); dc->TextOut(200,50,s,strlen(s)); } return 0; }

Trong chng trnh s dng hai bin tr lp CWinThread (pThread1, pThread2) tr n hai i tng tng ng l hai lung c to ra. Bin ttOnThread m thi gian theo tng giy hin ln ca s qua hm thng ip thi gian OnTimer(), ng thi quy nh chc nng ng vi hm OnThread() ch thc hin mt ln vi gi tr ttOnThread xut pht bng 0. Trong hm OnThread() sau khi khi to hai lung chng ta t mc u tin cho hai lung khc nhau, lung th nht c mc u tin cao nht (THREAD_PRIORITY_TIME_CRITICAL) v lung th hai c mc u tin thp nht (THREAD_PRIORITY_IDLE). Trong hm ca lung s dng lnh for sau to tr:
for (long j=1,i=0;i<1000000;i++) j=i-j+2*i-3*j;

Kt qu chng trnh sau 20 giy s l:

Ta thy hai gi tr m trn hai lung khc nhau, lung 1 c gi tr m cao hn nhiu so vi lung 2 chng t lung 1 c thc hin u tin hn.
298

Nu t mc u tin hai lung nh sau v bng mc bnh thng th kt qu sau 20 giy s l:

Hai gi tr m ca hai lung l nh nhau v ngc li nu t gi tr u tin cho lung 2 cao hn lung 1 th kt qu s l:

C ch x l hai hm ng vi hai lung trn l nh nhau, trong vng lp while vi iu kin l 5000 ln lp m v hin kt qu ln ca s. Gi tr 20 hin trn ca s l s giy thc hin lung, gi tr ny c hin bi hm x l thng ip thi gian OnTimer().

299

9.4. ng b ha trong lp trnh a tuyn


Khi nim ng b ha trong lp trnh a tuyn l ng b vic truy nhp ti nguyn trn my gia cc lung, ngoi ra c ng b cc s kin gia cc lung. Khi s dng nhiu lung hoc nhiu tin trnh v cc ti nguyn dng chung ch c php truy xut bi mt lung ti mt thi im. V d nh chng ta c mt lung ang ghi tp, mt lung khc cng ghi tp vo cng thi im th phi c ngn chn cho n khi lung trc ghi xong. Mt l do khc i vi s ng b ny khi mt lung ang ch mt s kin c sinh ra bi mt lung khc, trong trng hp ny th lung th nht phi c gi trng thi ch Suspend cho n khi s kin c xy ra. C hai trang thi ca mt cng vic c th l: th nht n ang hot ng, th hai n b kha (blocked).

9.4.1. C ch ng b ha
Windows cung cp cc dch v cho php truy xut cc ti nguyn dng chung mt cch hiu qu, nhng khng cung cp hng dn v cc dch v ny. Mt tin trnh hay lung khng th bit chi tit cch truy xut ti nguyn ca h thng. C th tng tng rng chng ta ang vit chng trnh trn h iu hnh a nhim m khng cung cp bt k mt c ch ng b no. Hn na khi hai tin trnh A v B ang cng truy xut mt ti nguyn R no trn h thng nhng ti nguyn ch c php mt tin trnh truy xut ti mt thi im, phi lm g ngn chn s xung t nh trn. Mt cch lm kh n gin l s dng mt gi tr c flag c khi to l 0, i vi mi tin trnh truy xut ti nguyn R, trc ht phi ch trng thi t c cho n khi bng 0 (ti nguyn R ri), sau khi c trng thi c bng 0 ta t li bng 1 v thc hin truy xut, xong ta hy c bng 0. Mu chng trnh nh sau:
300

while (flag); //ch gi tr c cho n khi bng 0 flag = 1; // ... truy xut ti nguyn dng chung y // flag = 0;

Gii php cho vn ng b ha cng n gin cng tt. H iu hnh cung cp mt hnh ng khng phi ngt l kim tra v t c nu c th. Trc y gi tr c c s dng iu khin ng b ha gia cc tin trnh c gi l semaphore.

9.4.2. i tng ng b ha
MFC cung cp 4 kiu i tng ng b ha, tt c u da trn khi nim semaphore. Kiu th nht l lp semaphore, mt semaphore c th cho php gii hn s tin trnh hoc lung truy xut ti mt ti nguyn, hoc cho php ch mt tin trnh hoc lung truy xut ti nguyn ti mi thi im. Semaphore l th hin cho vic s dng mt bin m s c tng khi cng vic gn ti semaphore v ngc li gim bin m khi cng vic c gii phng. i tng ng b th hai l mutex semaphore, s dng i tng ny ng b ti nguyn vi mi thi im ch c mt v ch mt tin trnh hoc lung c truy xut. Th ba l i tng event object, c s dng kha truy xut ti nguyn cho n khi mt lung hoc tin trnh bt tn hiu c th dng c. Cui cng bn c th ngn chn mt on m c s dng bi nhiu lung ti cng thi im bng cch t n vo trong critical section v s dng i tng critical section ny. Trong chng ny chng ti ch trnh by cch to v s dng hai i tng l semaphore v event.
301

9.4.3. Cc lp ng b ca MFC
MFC bao gi k thut ng b ha bi cc lp sau:
Tn l p CCriticalSection CEvent CMutex CSemaphore ngha i t ng ng b critical section i t ng event i t ng mutex semaphore i t ng semaphore

Cc lp ny u dn xut t lp CSyncObject, n cung cp k thut c s cho vic ng b ha. MFC cn nh ngha thm hai lp l CSingleLock v CMultiLock iu khin truy xut cc i tng ng b trn. Chng c cc thnh vin hm t v hy b mt i tng ng b. Lp CSingleLock iu khin truy xut ti mt i tng ng b, ngc li CMultiLock cho php iu khin truy xut nhiu i tng ng b. Chng ta s s dng lp CSingleLock minh ha, cn bn c th t minh ha thm v lp CMultiLock. Sau khi to mt i tng ng b, bn c th iu khin truy xut n bng cch s dng mt i tng CSingleLock. Trc ht bn s dng hm to ca lp to i tng CSingleLock theo mu sau:
CSingleLock( CSyncObject FALSE); *SyncOb, BOOL InitialState =

Trong SyncOb l con tr ti i tng ng b, nh l semaphore. Gi tr InitialState quy nh hm ny c i hi i tng ng b hay khng ng vi TRUE hoc FALSE. Mc nh l khng cn i tng ng b c tr bi SyncOb. Sau khi to i tng CSingleLock bn s dng n iu khin truy xut i tng ng b tng ng vi cc hm Lock() v UnLock() c khai bo nh sau:
BOOL BOOL CSingleLock :: Lock(DWORD dwDelay=INFINITE); CSingleLock :: UnLock();

302

BOOL CSingleLock :: UnLock(LONG Count, LONG *Previous=NULL);

Hm Lock() i hi phi c i tng ng b, lung ang thc hin s b ngng cho n khi hm ny tr v. Gi tr dwDelay l s mili giy cng vic ang thc hin ch i tng ng b. Hm tr v TRUE nu thnh cng v ngc li. Hm UnLock() hy b i tng ng b v cho php lung khc s dng n. Gi tr Count mu th hai quy nh s m i tng truy xut, thng s dng cho semaphore vi a truy xut ti nguyn, Previous s lu gi tr s m trc . Hm tr v TRUE nu thnh cng v ngc li. Cc bc thc hin ng b s dng i tng CSingleLock nh sau: Bc 1: To mt i tng ng b t mt trong 4 lp trn (CCriticalSection, CEvent, CMutex, CSemaphore) dng iu khin truy xut ti nguyn. Bc 2: To mt i tng lp CSingleLock s dng i tng ng b to trn. Bc 3: chn truy xut ti ti nguyn gi hm Lock(). Bc 4: Thc hin truy xut ti nguyn. Bc 5: Gi UnLock() hy b chn bi hm Lock().

V d 9.4
Lp trnh s dng i tng lp CSemaphore ng b ha hai lung MyThread1 v MyThread2 nh v d trc. Lp CSemaphore c mt hm to nh sau:
CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName = NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL );

Nhng chng ta s dng cc gi tr mc nh khi to i tng.

303

Ni dung chng trnh l:


#include<afxwin.h> #include<afxmt.h> #define IDM_THREAD 174 #define IDM_EXIT 142 UINT MyThread1(LPVOID pMain); UINT MyThread2(LPVOID pMain); int ttOnThread=0; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CSemaphore sema; int mY; CMyWin(); void OnThread(); void OnExit(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_COMMAND(IDM_THREAD,OnThread) ON_COMMAND(IDM_EXIT,OnExit) ON_WM_TIMER() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin()

304

{ Create(NULL,"Vi du 03 - Chuong 9"); CMenu mn; mn.CreateMenu(); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_THREAD,"Bat dau"); mn.AppendMenu(MF_STRING|MF_BYCOMMAND,IDM_EXIT,"Exit"); SetMenu(&mn); mY=0; } void CMyWin::OnThread() { if (ttOnThread) return; ttOnThread=1; AfxBeginThread(MyThread1,this); AfxBeginThread(MyThread2,this); } void CMyWin::OnExit() { DestroyWindow(); } UINT MyThread1(LPVOID pMain) { CMyWin *p = (CMyWin*)pMain; CDC *dc = p->GetDC(); long Count1=0; char s[100]; /* Kha ti nguyn s d ng i t ng l p CSingleLock */ CSingleLock syncOb(&(p->sema)); syncOb.Lock(); while (Count1<10) { sprintf(s,"{Count of Thread1 =%ld}",Count1++); dc->TextOut(0,p->mY,s,strlen(s)); p->mY +=15; Sleep(500); } /* H y kha ti nguyn */ syncOb.Unlock();

305

return 0; } UINT MyThread2(LPVOID pMain) { CMyWin *p = (CMyWin*)pMain; CDC *dc = p->GetDC(); long Count2=0; char s[100]; /* Kha ti nguyn s d ng i t ng l p CSingleLock */ CSingleLock syncOb(&(p->sema)); syncOb.Lock(); while (Count2<10) { sprintf(s,"{Count of Thread2 =%ld}",Count2++); dc->TextOut(200,p->mY,s,strlen(s)); p->mY +=15; Sleep(500); } /* H y kha ti nguyn */ syncOb.Unlock(); return 0; }

Trong lp ca s CMyWin khai bo thm hai thnh vin l i tng ng b sema kiu lp CSemaphore, thnh vin mY quy nh ta dng hin ch ln ca s. Lung ng vi hm MyThread1() s hin cc dng ch ti ct 0 cn lung MyThread2() s hin ti ct 200. Trong mi hm ny chng ta to i tng lp CSingleLock v gn n vi i tng ng b, trc khi thc hin cng vic phi gi hm Lock() kha khng cho lung khc c thc hin, sau khi lm xong ta gi li hm Unlock() hy b kha trn. Kt qu chng trnh s l:

306

Nu chng ta b c ch ng b, c th y chng ta b 2 lnh:


CSingleLock syncOb(&(p->sema)); syncOb.Lock();

trc khi thc hin trong mi lung v b lnh:


syncOb.Unlock();

sau khi thc hin xong ca lung . Ta c kt qu nh sau:

307

Tc l vic thc hin hai lung y s an xen nhau, khc vi ng b trn l thc hin xong lung 1 mi thc hin lung 2.

9.5. Bi tp
Bi tp 9.1
Lp trnh to hai lung thc hin hai cng vic sau: - Hin mt ch bt k ra ti v tr bt k trn ca s. - Hin dng ch h v tn bn chy ngang qua ca s t tri phi v ngc li.

Bi tp 9.2
Lp trnh to mt lung thc hin cng vic sau: - V mt qu bng bay trn ca s v phn x cnh theo gc i xng.

Bi tp 9.3
Lp trnh v mt m hnh t trn nh bitmap v np vo ca s o, to mt lung cho t chy trn ca s t tri qua phi bng cch chp ca s o vo cc v tr sau xa i v chp li...

Bi tp 9.4
Lp trnh v 5 nh bitmap tng ng l 5 ng tc i ca con ngi v np vo 5 ca s o, to mt lung cho 5 nh hin ln mn hnh theo th t minh ha ng tc i ca con ngi (ging hot hnh).

Bi tp 9.5
Lp trnh to hai lung thc hin hai vic sau: - V m hnh my bay bay ngang qua ca s - Thc hin bn n t v tr sng di ca s (c xc nh trc) khi nhn phm Enter v kim tra nu trng my bay th tng im ln 1, ngc li bay qu ca s th dng n. Lung to my bay c gi bt u theo thi gian c sau mt i lng ngu nhin thi gian no .

308

Chng 10 TH VIN LIN KT NG DLL


10.1. Cc khi nim c bn
10.1.1. Th vin DLL l g?
Th vin lin kt ng l mt tp cc hng, bin nh, hm, lp v cc i tng c nh ngha trong mt tp chng trnh khng thi hnh, tp ny s cung cp cho cc chng trnh thi hnh nhng thnh phn nh trn. Th vin lin kt ng s khng c dch v lin kt vi chng trnh dng n. Qu trnh lin kt s c thc hin khi chng trnh chy v my s np th vin vo b nh khi cn s dng n. Mt th vin lin kt ng c th c s dng cung cp cho nhiu chng trnh cng thc hin mt lc, khi ta gi l th vin lin kt ng c chia s. Ngc li l th vin lin kt ng khng chia s. Th vin lin kt ng l mt c im mnh ca lp trnh trn h iu hnh Windows. Mt lp trnh vin lun cn n s lin kt gia chng trnh ca mnh vi cc th vin ng khc.

10.1.2. Cc c trng
Khi nhiu chng trnh c dng chung mt on m lnh th bn a n vo trong mt th vin ng cung cp. Hn na trong chng trnh bn c cc on m lnh thc hin nhiu cng vic cc thi im khc nhau th bn a mi on vo mt th vin ng khi cn th np vo my thi hnh, lm gim kch thc chng trnh khi chy.

309

Mt iu chc chn na l khi bn thc hin bt c iu g vi th vin lin ng th bn c th lm tng t vi lp trnh i tng thnh phn (COM Component Object Model). So vi cc cng c COM v ATL (Active Template Library) th lp trnh th vin ng n gin hn nhiu, ngc li lp trnh COM v ATL cn u t nhiu thi gian v cng sc mi thc hin c.

10.1.3. Cc kiu DLL


C hai kiu th vin ng c th to trong lp trnh MFC l th vin DLL m rng MFC v th vin DLL thng thng. i vi th vin DLL thng thng c hai kiu lin kt l lin kt tnh hoc lin kt ng. Chng ta c th to th vin DLL theo lp trnh Win32 (lp trnh C) nhng y chng ta s s dng lp trnh da trn MFC. Trong mi th vin ng s c cc giao din vi chng trnh s dng n. Giao din ny l tp cc bin nh, con tr, hm v cc lp, chng c th c s dng bi chng trnh lin kt tng ng. i vi th vin DLL m rng MFC th cc giao din c th cha cc tham s, bin, gi tr kiu ca C++ v MFC v tt nhin c th s dng C++ v MFC lp trnh to ra DLL. Tuy nhin th vin DLL m rng MFC s c lin kt vi th vin ca bn thn MFC, do chng trnh lin kt tng ng phi c cng phin bn vi th vin MFC ca DLL. iu ny i khi gy kh nhiu phin toi cho ngi lp trnh cng nh ngi s dng. Th vin DLL m rng MFC thng c kch thc nh v lin kt nhanh vi chng trnh, tt nhin n cn ph thuc vo phn m lnh trong th vin . i vi th vin DLL thng thng th c th s dng trong hu ht cc chng trnh trn Windows, trong khi th vin DLL m rng MFC li ch c s dng bi chng trnh kiu MFC. Tuy vy trong th vin thng thng chng ta khng th cha trong giao din l cc kiu ca MFC hoc k tha t MFC. C th s dng MFC trong lp trnh to ra th vin DLL thng thng, khng a vo giao din.

310

Trong th vin DLL thng thng nu cn s dng n th vin MFC th chng ta c th chn gii php lin kt tnh (statically link) hoc lin kt ng (dynamically link). Trong trng hp lin kt ng th th vin DLL bn to ra s dng th vin MFC trn my thi hnh, do i hi phin bn th vin MFC phi thch hp vi yu cu trong DLL ca bn. Trng hp lin kt tnh th th vin DLL ca bn s rt ln nhng thc hin c lp trn my khi lin kt.

10.2. Cch xy dng th vin DLL


10.2.1. Cc bc to th vin DLL
Chng ta c th to mt th vin lin kt ng DLL theo cch t lm t u, tuy nhin trn mi trng VisualC++ cho php chng ta to ra th vin mt cch d dng hn, s dng cng c Wizard. Trong hp thoi ca chc nng "New" t thc n "File" chng ta chn th "Projects" v c mt trong 3 trng hp sau:

311

MFC AppWizard (dll) Th vin lin kt ng theo kiu lp trnh MFC (C++). Win32 Dynamic-Link Library Th vin lin kt ng kiu lp trnh C. Win32 Static Library Th vin lin kt tnh kiu lp trnh C.

(i)

(ii)

(iii)

Chng ta s chn trng hp (i) theo kiu lp trnh MFC. Nhp tn ca project tng ng l tn th vin v chn "OK" s xut hin bc tip theo.

Trong bc ny bn chn mt trong 3 kiu th vin lin kt ng nh trnh by trn: + Regular DLL with MFC statically linked To th vin lin kt ng thng thng v thc hin lin kt tnh vi th vin MFC, khi thi hnh khng ph thuc vo phin bn MFC trn my tnh. + Regular DLL using shared MFC DLL

312

To th vin lin kt ng thng thng s dng th vin MFC chia s, lin kt ng v s ph thuc vo phin bn MFC trn my tnh khi thi hnh th vin ny. + MFC Extension DLL ( using shared MFC DLL) To th vin lin kt ng kiu MFC v tt nhin s dng th vin MFC lin kt ng, vi th vin ny bn c th xut ra giao din cc kiu ca MFC v ph thuc vo phin bn MFC trn my tnh thi hnh th vin ny. Trong trng hp ny bn chn (i) dng n gin nht, tuy vy bn c th chn bt k trong 3 trng hp trn nu cn.

10.2.2. nh ngha giao din ca th vin DLL


Khc vi chng trnh thng thng, ngoi cc tp ti nguyn .RC, tp khai bo .H v tp ni dung .CPP th vin lin kt ng c thm mt tp cha nh ngha giao din cc thnh phn xut ra t th vin cc chng trnh lin kt c th dng. Tp ny c phn m rng l .DEF vi ni dung c bn nh sau:
; Tp nh ngha giao din th vin .DEF LIBRARY " tn ca th vin "

DESCRIPTION ' m t th vin ' EXPORTS ; Cc nh ngha thnh phn giao din y

Trong mt nh ngha thnh phn giao din c c php sau:


entryname[=internalname] [@ordinal[NONAME]]

Trong entryname l tn chnh thc ca thnh phn (bin nh, kiu d liu, lp, hm), thnh phn ny s c s dng bi cc chng trnh c lin kt vi th vin, internalname l tn ca thnh phn c khai bo v s dng trong th vin, ordinal l s th t thnh phn. Vi mt nh ngha thnh phn giao din ch cn tn chnh thc, lc ny tn cng l tn c khai bo v s dng bn trong th vin. V d nh ngha mt giao din:
313

; vidu_dll3.def : Declares the module parameters for the DLL. LIBRARY "vidu_dll3" DESCRIPTION 'vidu_dll3 Windows Dynamic Link Library' EXPORTS MAX @1 MIN @2 SUM @3 CMyClass @4

Tuy nhin bn c th nh ngha cc thnh phn giao din cho th vin khng cn tp .DEF ny v bn phi nh ngha trong chng trnh th vin, tp .H hoc tp .CPP. Khi c php khai bo s l:
__declspec(dllexport) khai-bo-thnh-phn;

Trong khai bo thnh phn c th l khai bo bin, khai bo hm. i vi khai bo lp chng ta lm theo cch sau:
class __declspec(dllexport) khai-bo-lp;

Trong trng hp ny bn phi dng t kha __declspec(dllexport) thc hin, c th nh ngha t ny thnh mt hng thay th n gin v ngn hn. V d:
#define MYDEC __declspec(dllexport) class MYDEC CVidu_dll2 { public: CVidu_dll2(void); }; MYDEC int nVidu_dll2; MYDEC int fnVidu_dll2(void);

Vi cch nh ngha giao din qua tp .DEF s em li nhiu li im nh vic thm cc thnh phn mi vo giao din theo s th t (@ordinal) tng dn s khng nh hng n chng trnh s dng n. Sau khi bn nng cp DLL thnh mt phin bn mi th chng trnh ng dng s dng phin bn DLL c s lm vic tng thch vi phin bn DLL mi ny, khng cn phi dch li chng trnh ng dng. Ngoi ra nu bn s dng NONAME trong khai bo s khng s dng tn trong th vin v lm gim kch thc ca th vin.

314

Hnh minh ha s lin kt gia th vin lin kt ng vi chng trnh ng dng nh sau:

V d 10.1
Lp mt th vin DLL xut ra giao din lp CMyClass cc i tng phn s x l cng phn s v rt gn phn s, xut thm mt bin s nguyn m v mt hm sum tnh tng hai s nguyn.
/* T p khai bo header vidu01.h nh sau */ class CVidu01App : public CWinApp { public: CVidu01App(); }; __declspec(dllexport) int m=7; __declspec(dllexport) int sum(int x,int y); class __declspec(dllexport) CMyClass { int ts,ms; public: CMyClass(int x=1,int y=1);

315

CMyClass operator + (CMyClass vp); void rutgon(); }; /* T p chng trnh vidu01.cpp nh sau */ #include<afxwin.h> #include<math.h> #include "Vidu01.h" CVidu01App::CVidu01App(){} CVidu01App theApp; CMyClass::CMyClass(int x,int y) { ts=x; ms=y; } CMyClass CMyClass::operator + (CMyClass vp) { CMyClass kq; kq.ts = ts*vp.ms + vp.ts*ms; kq.ms = ms*vp.ms; return kq; } void CMyClass::rutgon() { if (ts*ms==0) return; int a=abs(ts), b=abs(ms); while (a!=b) { if (a>b) a=a-b; else b=b-a; } ts=ts/a; ms=ms/a; } int sum(int x,int y) { return x+y; }

316

10.3. S dng DLL trong chng trnh


Mt th vin lin kt ng khng t n thi hnh trn my, m do mt chng trnh ng dng np v s dng n qua giao din tng ng. Khi bn dch th vin DLL th my s to ra hai tp .DLL v .LIB, c hai tp ny quan trng khi lin kt vi chng trnh ng dng. Mt chng trnh s dng th vin lin kt ng c hai phng php l phng php khng tng minh (implicite) hoc phng php tng minh (explicite).

10.3.1. Lin kt khng tng minh


Lin kt ny s thc hin np th vin ng vo my mi ln chy chng trnh ng dng (load-time dynamic linking). Cc bc thc hin nh sau: Bc 1: Bn phi chp c hai tp ca th vin ng l .DLL v .LIB vo th mc ca chng trnh thc hin lin kt. Bc 2: Bn thit lp cho chng trnh ca bn c thm lin kt vi th vin DLL bng cch chn chc nng "Project" "Setting" Chn th "Link" trn hp thoi ny v g vo "Object/Library modules" tn tp .LIB ca th vin ng tng ng. Bc 3: Trong chng trnh bn phi khai bo nhn cc thnh phn c s dng t giao din ca th vin ng bng c php sau:
__declspec(dllimport) khai-bo-thnh-phn;

Chng ta thy khai bo ny tng t nh khai bo giao din cho th vin ng nhng y s dng t kha dllimport thay cho dllexport. V d:
__declspec(dllimport) int m=7; __declspec(dllimport) int sum(int x,int y); class __declspec(dllimport) CMyClass;

Bc 4: Bn c th dng cc thnh phn khai bo nh bnh thng trong chng trnh.

317

V d 10.2
Lp chng trnh s dng th vin v d 10.1 thc hin cng hai s nguyn, cng hai phn s v hin kt qu ln ca s. Ni dung tp chng trnh s l:
#include<afxwin.h> __declspec(dllimport) int m; __declspec(dllimport) int sum(int x,int y); class __declspec(dllimport) CMyClass { int ts,ms; public: CMyClass(int x=1,int y=1); CMyClass operator + (CMyClass vp); void rutgon(); int getTS(); int getMS(); }; class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); void OnPaint(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_WM_PAINT() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow();

318

return TRUE; } CMyWin::CMyWin() { Create(NULL,"Chuong trinh su dung DLL - vidu10.2"); } void CMyWin::OnPaint() { CPaintDC dc(this); char s[200]; sprintf(s,"sum(5,19) is %d",sum(5,19)); dc.TextOut(10,10,s,strlen(s)); sprintf(s,"varible m is %d",m); dc.TextOut(10,40,s,strlen(s)); CMyClass a(5,7),b(3,5),c; c = a+b; sprintf(s,"(a=%d/%d) + (b=%d/%d) is (c=%d/%d)", a.getTS(),a.getMS(),b.getTS(),b.getMS(), c.getTS(),c.getMS()); dc.TextOut(10,70,s,strlen(s)); }

Kt qu chy th chng trnh s l:

Chng ta thy vic s dng th vin ng theo kiu lin kt khng tng mnh (implicite) s kh phc tp, thc hin kh nhiu bc trong chng trnh.

319

10.3.2. Lin kt tng minh


Lin kt tng minh s thc hin lin kt mi khi chng trnh cn n th vin, do th vin s khng c np vo my khi chng trnh chy m chng ta phi thc hin np th vin bng cc cu lnh trong chng trnh. thc hin c lin kt tng minh chng ta phi khai bo cc thnh phn giao din trong th vin DLL qua tp .DEF vi t kha EXPORTS. Cc bc thc hin lin kt tng minh: Bc 1: Gi hm LoadLibrary() np th vin DLL vo my v lu gi s hiu ca module tng ng vi th vin c np. Mu hm khai bo nh sau:
HMODULE LoadLibrary( LPCTSTR filename );

Trong filename l tn tp ca th vin cn np vo my, c th bao gm c ng dn. Nu thnh cng hm tr v s hiu nh danh (HMODULE hoc HINSTANCE) th vin c np, ngc li tr v NULL. Trong trng hp khng c ng dn th my s t ng tm trn cc th mc ca h thng nh: th mc hin ti, th mc h thng, th mc windows,... Bc 2: Gi hm GetProcAddress() xc nh a ch ca mt hm trong th vin sau khi c np, a ch hm ny c lu bi con tr hm v dng gi hm. Mu hm khai bo nh sau:
FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName );

Trong hModule l s hiu ca th vin c ly t gi tr tr v bi hm LoadLibrary(), lpProcName l tn ca hm trong mun th vin cn ly a ch. Hm tr v kiu con tr hm tng ng vi tn hm. Mu khai bo kiu con tr hm lu a ch ca mt hm nh sau:
typedef s); kiu-hm (CALLBACK *kiu-con-tr)( cc-kiu-tham-

320

Sau dng kiu-con-tr khai bo cc con tr lu a ch hm cn s dng trong chng trnh. V d:


typedef UINT (CALLBACK* FPointer)(DWORD,UINT); .. HINSTANCE hDLL; // Handle to DLL FPointer lpfnDllFunc1; // Function pointer DWORD dwParam1; UINT uParam2, uReturnVal; hDLL = LoadLibrary("MyDLL"); if (hDLL != NULL) { lpfnDllFunc1 = (FPointer)GetProcAddress(hDLL, "DLLFunc1"); if (!lpfnDllFunc1) { // handle the error FreeLibrary(hDLL); return SOME_ERROR_CODE; } else { // call the function uReturnVal = lpfnDllFunc1(dwParam1, uParam2); } }

Bc 3: Gi hm FreeLibrary() sau khi s dng xong cc hm trong th vin. Mu hm nh sau:


BOOL AFXAPI FreeLibrary( HMODULE hInstLib );

Trong hInstLib l s hiu th vin cn gii phng.

V d 10.3
Lp trnh to mt th vin c khai bo giao din qua tp .DEF v lp mt chng trnh s dng th vin np v thc hin cc hm trong th vin. Th vin y chng ta thit k c 2 hm nh sau:

321

int int

max(int *a, int n); sum(int *a, int n);

Bc 1: Xy dng th vin, to hai tp vidu03lib.cpp v vidu03lib.def vi ni dung nh sau:


// T p nh ngha giao di n cho th vi n LIBRARY "vidu03lib.dll" DISCRIPTION 'thu vien cho vidu03' EXPORTS myMAX @1 mySUM @2 // T p chng trnh th vi n cho v d 03 #include<afxwin.h> class CMyLib : public CWinApp { public: CMyLib() { AfxMessageBox("Bat dau cua thu vien DLL"); } }; CMyLib theLib; int myMAX(int *a,int n) { for (int m=0,i=0; i<n;i++) if (a[m]<a[i]) m=i; return a[m]; } int mySUM(int *a,int n) { for (int s=0,i=0; i<n;i++) s=s+a[i]; return s; }

Sau khi dch th vin trn ta c tp vidu03lib.dll v chp vo th mc h thng ca Windows lin kt. Bc 2: Xy dng chng trnh c s dng th vin trn gm mt tp main.cpp nh sau:

322

#include<afxwin.h> class CMyApp : public CWinApp { public: BOOL InitInstance(); }; class CMyWin : public CFrameWnd { public: CMyWin(); void OnPaint(); DECLARE_MESSAGE_MAP() }; CMyApp theApp; BEGIN_MESSAGE_MAP(CMyWin,CFrameWnd) ON_WM_PAINT() END_MESSAGE_MAP() BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWin; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyWin::CMyWin() { Create(NULL,"Lien ket DLL tuong minh - vidu10.3"); } void CMyWin::OnPaint() { CPaintDC dc(this); typedef int (CALLBACK *FPointer)(int*,int); FPointer fp; HINSTANCE h1; h1= LoadLibrary("vidu03lib"); if (h1==NULL) { AfxMessageBox("Khong nap duoc thu vien 'vidu03lib.dll'"); return; } int a[5]={1,54,2,-12,5};

323

int n=5; char s[100]; fp=(FPointer)GetProcAddress(h1,"mySUM"); if (fp!=NULL) { sprintf(s,"SUM is %d",fp(a,n)); dc.TextOut(10,10,s,strlen(s)); } fp=(FPointer)GetProcAddress(h1,"myMAX"); if (fp!=NULL) { sprintf(s,"MAX is %d",fp(a,n)); dc.TextOut(10,40,s,strlen(s)); } FreeLibrary(h1); }

Kt qu chy chng trnh trn mn hnh s l:

10.4. Bi tp
Bi tp 10.1
Lp trnh to mt th vin c cc hm thc hin cc thut ton trn mng nh: sp xp, o ngc, xa b phn t, chn thm phn t, tm max, tm min, tnh tng. Lp chng trnh s dng th vin trn thc hin cc thut ton v hin kt qu ln ca s.

Bi tp 10.2
Lp trnh to mt th vin c mt lp hot ng theo kiu stack v mt lp hot ng theo kiu queu trn d liu s thc.

324

Lp chng trnh s dng th vin m phng hai cu trc d liu ny ln ca s. Cho php nhp vo mt s v y vo stack v queu, cho php loi b phn t trong stack v queu.

Bi tp 10.3
Lp mt th vin c mt hm v ngi sao gm n cnh, vi bn knh ngoi v bn knh trong ca ngi sao l R v r. V thng qua mt DC ca ca s no . Lp chng trnh s dng th vin trn nhp vo 3 s n, R, r v ln ca s ngi sao .

Bi tp 10.4
Xy dng mt th vin cha cc hm tnh ton v x l cc php ton ma trn nh: nhn, cng, tm max theo hng, theo ct, Lp chng trnh s dng th vin trn th nghim.

Bi tp 10.5
Xy dng mt th vin cha cc hm x l php tnh ton s nguyn ln gm: php cng, tr, nhn, chia. Lp chng trnh s dng th vin trn th nghim.

325

Chng 11 LP TRNH ACTIVEX


11.1. Cc khi nim c bn
ActiveX l mt trong nhng nguyn l lp trnh trn Windows rt hay, tuy nhin tng i kh nm vng v trin khai c nguyn l ny. N ng vai tr rt quan trng trong vic pht trin phn mm trn Windows. H thng con ActiveX l rt ln v rt phc tp, v vy trong ti liu ny ch dng li mc trnh by n gin v tng bc lm quen vi nguyn l ny qua cc v d. iu khin ActiveX i hi nhiu k thut lp trnh phc tp hn, do chng ta cn nm kh nhiu vn y. Tuy nhin mt cch n gin l chng ta s dng "ActiveX Control Wizard" cung cp bi Visual C++ thc hin. Chng ti s c gng trnh by vi cch n gin nht bn c th hiu c cc vn trong lp trnh ActiveX.

11.1.1. Khi nim v ActiveX


ActiveX l mt tp cc phng thc v th tc cho php bn to cc b phn cu thnh phn mm (software component). Mt software component c th c s dng li nhiu chng trnh khc nhau. Software component l mt trong cc ch n ca cng ngh phn mm. i vi mt h thng n vic s dng software component khng mang ngha ln bi cc ng dng s ci t y v ngi dng mun nng cp th phi ci t mi mt phin bn phn mm tt hn. u im ln ca software component l vic s dng trn mng, khi c yu cu s dng thnh phn ng dng trn mt my trm th n s c

326

download t ng t my ch. T khi c Internet chng ta thy cc ng dng (c bit nh World Wide Web) u phi s dng k thut ny. Cc software component c ci t trn my ch Web v ch khi no Website yu cu thc hin mt chc nng th thnh phn tng ng s c ti xung my trm v thc hin.

11.1.2. OLE v ActiveX


OLE (Object Link Embed) l mt bc tin bt u cho vic hnh thnh k thut lp trnh ActiveX. Bc u OLE c thit k cho php cc ng dng lin kt (Link) hoc nhng (Embed) thng tin c to ra bi cc ng dng khc, khi mt ti liu kt hp c to ra. OLE tri qua mt bc pht trin kh di bt u t nm 1991, cho n nay l phin bn OLE 3.0 v c nh ngha thm c tnh Component Object Model (COM). c tnh ny dn ti cng ngh ActiveX ngy nay. p ng cho cc ng dng v dch v trn mng Internet, Microsoft nh ngha ActiveX vo nm 1996. Da trn k thut OLE, n cung cp thm cho cc ng dng Web. Tuy nhin t khi ActiveX ra i v cung cp tt c nhng g m OLE c th thut ng OLE gn nh b qun lng.

11.1.3. Component Object Model (COM)


ActiveX da trn m hnh i tng thnh phn (COM). M hnh ny nh ngha cch tng tc gia cc ng dng c cha ActiveX vi nhau. c bit n nh ngha giao din chun mt i tng c th s dng a ra cc chc nng ca n ti cc i tng khc. Trong m hnh i tng thnh phn c hai kiu ng dng: kiu cha (container) v kiu ch (server). Trong kiu cha th ng dng s yu cu d liu, cn kiu ch th ng dng s cung cp d liu. Mt thut ng khc ca container l client (khch). Cch mt client (container) v server giao tip vi nhau thng qua giao din c nh ngha bi COM. ActiveX cng s dng giao din ca m hnh COM v mt iu khin ActiveX s nm trong x l ch (server), cn ng dng s dng ActiveX c th coi l khch (client).

327

11.1.4. Giao din COM


Giao din COM c th hin nh l mt bng cc con tr hm, nhng con tr ny tr ti cc hm c trong th vin (OLE hoc ActiveX). a ra mt giao din, server tr v mt con tr ti bng ca giao din tng ng. Khi client tm lin lc vi server, n cha mt con tr ti bng giao din tng ng trn server. Client sau gi cc hm c cung cp bi server qua cc con tr trong bng hm. Client khng bit hoc khng truy xut c thng tin chi tit cc hm m n gi. N ch bit l ang truy xut mt hm chun thng qua giao din chun. Tt c cc giao din COM c nh ngha bi mt b nh danh ton cc duy nht - Globally Unique IDentifier (GUID), n phn bit mt giao din COM vi nhng giao din COM khc. nh danh duy nht ny c to nn t 11 phn bao gm 1 gi tr long, 2 gi tr WORD v 8 gi tr BYTE. Cc gi tr ny thng c sinh ra bi cng c th 3, c th s dng cng c GUIDGEN thc hin. Hu ht ActiveX u th hin cc giao din nh ngha bi COM, tuy nhin c mt giao din m ActiveX dng l IUnknown. S dng hm QueryInterface() c nh ngha bi IUnknown mt ng dng c th tm thy cc giao din c trong ng dng khc. Gi tr c bn trong giao din l mt ng dng cha COM c th tn dng nhng u im ca cc chc nng cung cp bi nhng chng trnh COM.

11.1.5. MFC v ActiveX


MFC cung cp cng ngh ActiveX c gi l OLE Controls Developer Kit (CDK) v n nm trong mt phn ca th vin MFC. Cng ngh ActiveX trong MFC l s kt hp gia cc lp (class) v cc macro, gm 3 lp chnh l COleControlModule, COleControl, COlePropertyPage. Ngoi 3 lp ny cn c mt tp cc macro c nh ngha xy dng v pht trin iu khin ActiveX. Lp COlePropertyPage th hin giao din ha ca bng thuc tnh cho iu khin ActiveX. Lp ny c th khng cn s dng trong xy dng iu khin ActiveX v chng ta s khng cp n nhiu trong chng ny.
328

Ngoi ra MFC cn cung cp cc cng c pht trin nh cng c sinh cc gi tr nh danh GUID, cng c kim th iu khin ActiveX, cng c sinh chng trnh khung xy dng iu khin ActiveX.

11.2. Xy dng iu khin ActiveX


Khc vi nhng chng trnh ng dng trc y, chng trnh ActiveX kh phc tp v cch tip cn khc vi chng trnh ng dng. i vi mt chng trnh ng dng bao gm cc thnh phn c bn sau: - Kiu ng dng l chng trnh thi hnh trn Windows - Chng trnh cha mt lp dn xut ca CWinApp v mt lp dn xut ca CWnd - Chng trnh cha mt hoc nhiu kiu ti nguyn Chng trnh ActiveX c chia s mt vi c tnh ca chng trnh ng dng, tuy nhin c mt s iu khc bit nh sau. Chng trnh ActiveX c th hin nh mt th vin lin kt ng, khc vi mt chng trnh ng dng thi hnh nh trc y. Kiu chng trnh DLL s thch hp hn cho cc i hi ca software component, bi v n thit k di dng mun v c s dng bi cc client (ng dng) khc. Tp tin th vin DLL th hin cho iu khin ActiveX c phn m rng l OCX (OLE Control Extension) thay cho DLL. Tng t mt th vin lin kt ng DLL, chng trnh dng ActiveX cn mt tp cha cc nh ngha. Mun ny thc hin hai vic l: th nht l khai bo tn cc hm c xut ra bi DLL, n chnh l cc hm trong iu khin ActiveX nhng c gi t cc chng trnh client ngoi; th hai l khai bo hai hm DllRegisterServer() v DllUnregisterServer(), cho php iu khin t ng k trong h thng, khi n s cp nht cc thng tin cn thit vo ng k h thng (registry). Tp cha mun nh ngha c phn m rng l DEF. Mt v d khai bo trong tp DEF l:

329

// T p vidu01.DEF LIBRARY "VIDU01.OCX" EXPORTS DllCanUnloadNow @1 PRIVATE DllGetClassObject @2 PRIVATE DllRegisterServer @3 PRIVATE DllUnregisterServer @4 PRIVATE

Mt thnh phn khc quan trng l tp tin ngn ng m t i tng (Object Description Language - ODL), c phn m rng tng ng l ODL. Trong tp ny cha m t cc giao din c th hin bi i tng iu khin, n s c dch vo trong tp th vin ca iu khin tng ng. Mt v d ca tp ODL nh sau:
// T p vidu01.ODL #include <olectl.h> #include <idispids.h> [ uuid(12CD1DBB-0FAA-42A1-B5D7-BE2DCF1E48A8), version(1.0), helpfile("Vidu01.hlp"), helpstring("Vidu01 ActiveX Control module"), control ] library VIDU01Lib { importlib(STDOLE_TLB); importlib(STDTYPE_TLB); // Primary dispatch interface for CVidu01Ctrl [ uuid(14253E53-34FE-404B-AEEF-7023A0B32C79), helpstring("Dispatch interface for Vidu01 Control"), hidden ] dispinterface _DVidu01 { properties: methods: }; // Event dispatch interface for CVidu01Ctrl [ uuid(708CED8D-F919-41FE-8DAF-86846D5F4528), helpstring("Event interface for Vidu01 Control") ] dispinterface _DVidu01Events { properties: methods:

330

}; // Class information for CVidu01Ctrl [ uuid(AADFA311-1DB0-4053-8ADF-FCC79ED405B6), helpstring("Vidu01 Control"), control ] coclass Vidu01 { [default] dispinterface _DVidu01; [default, source] dispinterface _DVidu01Events; }; };

Trong tp v d ODL ny c hai giao din rng. Th nht l giao din chuyn pht chnh (primary dispatch interface), c tn _Dmycontrol. Giao din ny s th hin cho cc thuc tnh v phng thc ca iu khin ActiveX. Giao din th hai c tn l _DmycontrolEvents, cha cc s kin ca iu khin khi thi hnh. Tuy nhin chng ta cha khai bo cc thuc tnh, phng thc v s kin trong v d trn. Chng ta hy ch ti cc gi tr phc tp v c v nh v ngha v d trn, chnh l cc nh danh duy nht c sinh bi cng c GUIDGEN. Gi tr GUID th nht l nh danh ca th vin cha iu khin, GUID th 2 v th 3 tng ng l nh danh chnh v nh danh cc s kin ca giao din. Cui cng l nh danh cho coclass ca i tng mycontrol. Ngoi ra chng ta c tp khai bo v ti nguyn chun, v d nh sau:
// T p resource.H #define IDS_VIDU01 1 #define IDD_PROPPAGE_VIDU01 200 #define IDB_VIDU01 1 // T p vidu01.RC #include<afxres.h> #include"resource.h" STRINGTABLE DISCARDABLE BEGIN IDS_VIDU01 "Vidu01 Control" END 1 TYPELIB "Vidu01.tlb"

331

Ti nguyn bitmap trn c nh danh l IDB_MYCONTROL phi l mt nh bitmap c kch thc 16x15 pixels. Bitmap ny s hin th trn thanh cng c cho iu khin ActiveX khi s dng. Lnh cui cng trong tp ti nguyn l:
1 TYPELIB "Vidu01.tlb"

n ch ra tp ti nguyn ny s c bao gm vo trong th vin chng trnh. Trong v d trn chng ta t tn th vin l "mycontrol.lib", vi nh danh l 1. Trong chng trnh iu khin ActiveX cn c cc tp tin chnh cha cc lp v ni dung chng trnh. Cc tp ny th hin s ci t cc lp gm lp mun iu khin COleControlModule v lp iu khin ActiveX COleControl.

11.2.1. Lp COleControlModule
Mt iu khin ActiveX ng vai tr nh mt in-process server, khc vi mt ng dng c lp. iu khin s cha mt i tng mun bn trong , to ra t lp COleControlModule. Khc vi ng dng trc y l lp CWinApp s cha framework. Mc ch s dng hai lp ny l nh nhau. Lp COleControlModule tha k hai hm l InitInstance() v ExitInstance(). Hai hm ny c th c vit trong lp dn xut ca COleControlModule tng ng, chng thc hin cc cng vic khi to v kt thc mun ca iu khin ActiveX. Tuy nhin chng ta khng cn thc hin g nhiu i vi lp COleControlModule, ch gn gi hai hm lp c s tng ng. Mt v d ca hai hm trong lp dn xut:
BOOL l p_d n_xu t :: InitInstance() { return COleControlModule::InitInstance(); } BOOL l p_d n_xu t :: ExitInstance() { return COleControlModule:: ExitInstance(); }

332

11.2.2. Lp COleControl
Trng tm ca xy dng iu khin ActiveX l lp dn xut ca lp COleControl. Lp ny cung cp cc tnh nng nh lp dn xut ca CWnd trong chng trnh ng dng. N ci t cho tt c cc giao din v cc hm ngi dng ca iu khin ActiveX. Trong lp dn xut ca COleControl, thng bn khai bo mt cu t (hm to) thc hin cc khi to giao din s kin v phn phi chnh m iu khin cung cp. khi to giao din chng ta phi gi hm COleControl::InitializeIIDs(), c khai bo nh sau:
void COleControl :: InittializeIIDs( const IID *DispatchInterface, const IID *EventInterface);

Trong DispatchInterface l mt con tr ti giao din phn phi chnh ca iu khin, trong v d trn l _Dmycontrol v EventInterface l mt con tr ti giao din s kin, trong v d trn l _DmycontrolEvents. Hai tham s ny do chng ta truyn vo v cc gi tr nh danh duy nht GUID c sinh bi GUIDGEN nm trong tp ODL ca chng trnh. Thng thng hai bin kiu IID truyn vo hm trn c nh ngha trong chng trnh t bng hai gi tr GUID tng ng. V d khai bo hai bin tng ng truyn vo cho hm InitializeIIDs() theo v d trn l:
const IID BASED_CODE IID_DVidu01 = { 0x14253e53, 0x34fe, 0x404b, { 0xae, 0xef, 0x70, 0x23, 0xa0, 0xb3, 0x2c, 0x79 } }; const IID BASED_CODE IID_DVidu01Events = { 0x708ced8d, 0xf919, 0x41fe, { 0x8d, 0xaf, 0x86, 0x84, 0x6d, 0x5f, 0x45, 0x28 } };

Nu iu khin ActiveX ca bn c hin th trong chng trnh khi s dng th cn phi vit hm COleControl::OnDraw(). Hm ny tng t nh hm OnDraw() ca lp CWnd, v li ca s khi cn thit. Hm c khai bo nh sau:

333

virtual

void

COleControl::OnDraw( CDC *DC, const CRect const CRect &ControlRect, &InvalidateRegion);

Trong tham s DC l con tr ti ng cnh thit b s dng bi iu khin. ControlRect l vng hin ti c hin th bi iu khin v InvalidateRegion l vng c th v li. Chng ta c th thc hin v ty ln vng ny. Chng ta s dng cc macro thc hin cc khai bo trn c d dng hn trong vic xy dng chng trnh, bao gm cc macro sau:

11.2.3. Cc macro ca ActiveX


Trong cc chng trc chng ta c cc macro nh ngha nh: + DECLARE_MESSAGE_MAP(), + DECLARE_DYNCREATE(), + BEGIN/END_MESSAGE_MAP(), + IMPLEMENT_DYNCREATE(). - Macro to lp ng Lp ca iu khin ActiveX cng l lp ng, c to ra bi yu cu ca chng trnh s dng, do cn phi s dng cp macro DECLARE_DYNCREATE() v IMPLEMENT_DYNCREATE() thc hin trong lp dn xut ca COleControl. - Macro cho lp factory to mt thi hnh ca iu khin ActiveX, chng trnh s dng iu khin phi gi mt hm thnh vin ca lp "factory" ca iu khin. Lp factory l mt lp c lp p ng cho vic to mt i tng ca lp khc, y l lp dn xut COleControl. Lp factory ny p ng yu cu cho mi i tng dng COM. Khai bo lp factory ny phi s dng cp macro vi khai bo nh sau:
DECLARE_OLECREATE_EX( tn_lp )

334

IMPLEMENT_OLECREATE_EX( tn_lp, tn_ngoi, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8 )

Trong tn_lp l tn ca lp iu khin s c to bi lp factory ny, tn_ngoi l ca iu khin. Tn ngoi ny c s dng bn ngoi (trong chng trnh dng iu khin ) v nh danh iu khin c to ra. Cc tham s cn li l cc gi tr ca GUID cho i tng coclass trong tp ODL, n bao gm mt gi tr long (l), 2 gi tr word (w1, w2) v 8 gi tr byte (b1,b2,...,b8). - Macro cho kiu th vin Mi iu khin ActiveX u s dng mt kiu th vin (library) m t cc giao din a ra cho chng trnh dng n. th hin kiu th vin cho iu khin ActiveX, MFC cung cp hai macro sau:
DECALRE_OLETYPE( class_name ) IMPLEMENT_OLETYPELIB ( class_name, typelib, vermajor, verminor)

Trong class_name l tn lp iu khin c m t bi th vin, typelib l gi tr GUID ca th vin c tm thy khai bo u tin trong tp ODL, vermajor v verminor l hai gi tr m t phin bn ln nh ca kiu th vin. V d phin bn 1.0 th vermajor l 1 v verminor l 0. Thng thng gi tr typelib c nh ngha di dng mt hng theo gi tr GUID trong tp ODL, s dng kiu GUID CDECL khai bo vi v d nh sau:
const GUID CDECL BASED_CODE _tlid = { 0x12cd1dbb, 0xfaa, 0x42a1, { 0xb5, 0xd7, 0xbe, 0x2d, 0xcf, 0x1e, 0x48, 0xa8 } };

- Macro cho kiu iu khin v trng thi khi to Cp macro tip theo s m t tn ngoi ca lp iu khin v mt s kiu trng thi khc, cp ny c khai bo trong lp iu khin. Tn ngoi l mt chui k t, s hin th trong giao din cc thnh phn ca chng trnh dng iu khin ActiveX. Chui ny c nh ngha trong ti nguyn bng chui STRING v c tham chiu bi mt gi tr nh danh ID. Trong v d trn th gi tr ny l IDS_MYCONTROL.

335

Cc kiu trng thi khc l nhng gi tr c hnh thnh khi iu khin c to v np vo ng dng. iu ny m bo ng dng khng bt buc phi np y cc tham s trng thi khi dng iu khin ActiveX. N bao gm mt hoc nhiu gi tr sau:
Gi tr OLEMISC_SETCLIENTSITEFIRST OLEMISC_INSIDEOUT OLEMISC_CANTLINKINSIDE OLEMISC_RECOMPOSEONRESIZE ngha i u khi n s truy xu t cc thu c tnh khi c n p i u khi n c th c kch ho t khng qua giao di n ng i dng i u khi n khng h tr lin k t v i bn ngoi i u khi n s t v l i n u c thay i

S dng cp macro sau khai bo tn ngoi ca lp v trng thi khc:


DECLARE_OLECTRLTYPE (c_name ) IMPLEMENT_OLECTRLTYPE( c_name , e_name, miscStatus )

Trong c_name l tn ca lp iu khin c m t trong th vin, e_name l ngoi ca iu khin s dng bi ng dng cha n v miscStatus l cc gi tr trng thi bng trn. - nh x thng ip v nh x giao din Trong lp trnh ng dng s dng cp macro sau khai bo thc hin nh x cho cc thng ip ti cc hm thnh vin, DECLARE_MESSAGE_MAP() v BEGIN/END_MESSAGE_MAP(). Tuy nhin trong lp iu khin ActiveX chng ta phi thc hin thm chuyn pht v nh x s kin. Giao din chuyn pht s a ra cc thuc tnh v phng thc cung cp bi iu khin ActiveX ti ng dng. Cp macro thc hin iu ny l:
DECLARE_DISPATCH_MAP()

v:
BEGIN_DISPATCH_MAP( owner , base ) END_ DISPATCH_MAP()

Trong owner l tn lp c nh x giao din chuyn pht, base l tn lp c s ca lp owner. Lp nh x chuyn pht lun l lp dn xut t COleControl.
336

nh x cc s kin cho iu khin ActiveX chng ta s dng cp macro sau:


DECLARE_EVENT_MAP()

v:
BEGIN_EVENT_MAP( owner, base ) END_EVENT_MAP()

Trong owner l tn lp thc hin nh x s kin lun l lp dn xut t COleControl v base l lp COleControl.

11.2.4. ng k iu khin
Mt iu khin ActiveX trc khi c s dng bi cc ng dng, lp iu khin v server (DLL) ca n phi c ng k vi h thng Windows. ng k ny bao gm mt vi khon mc trong c s d liu ng k. Cc khon mc ny m t nhiu mt ca lp iu khin ActiveX: + Kiu i tng iu khin + V tr ca server (DLL cha iu khin) + Cc gi tr khi to + nh bitmap s dng hin th cho iu khin trn thanh cng c + V tr v nh danh ca kiu th vin (library) + Phin bn ca iu khin - ng k lp iu khin ng k lp iu khin ActiveX c thc hin bng cch vit hm COleObjectFactory::UpdateRegistry(), hm c khai bo nh sau:
virtual void COleObjectFactory::UpdateRegistry(BOOL reg)=0;

Vy hm ny l mt hm o nguyn thy, do trong lp dn xut t phi vit n vi tham s regcls quy nh c s d liu ng k c cp nht hay khng tng ng vi gi tr TRUE hoc FALSE. Trong hm vit ny chng ta phi gi n hm AfxOleRegisterControlClass() thc hin ng k, vi khai bo hm nh sau:
337

BOOL

AFXAPI

AfxOleRegisterControlClass( HINSTANCE hInstance, REFCLSID clsid, LPCTSTR pszProgID, UINT idTypeName, UINT idBitmap, int nRegFlags, DWORD dwMiscStatus, REFGUID tlid, WORD wVerMajor, WORD wVerMinor );

Tt c cc tham s u bt buc truyn vo cho hm khi thc hin, c gii thch bi bng sau:
Tn tham s hInstance clsid pszProgID idTypeName idBitmap nRegFlags ngha Gi tr nh danh c a i t ng i u khi n, n chnh l gi tr nh danh c a mun ch a i u khi n nh danh c a l p, l GUID c a l p i t ng i u khi n n m trong t p ODL Gi tr GUID c a i u khi n n m trong t p ODL S hi u ti nguyn chu i ng v i tn i u khi n S hi u ti nguyn bitmap ng v i bi u t ng Gi tr ch a m t ho c hai gi tr sau: * afxRegApartmentThreading - kha ng k * afxRegInsertable - c xu t hi n trong h p tho i chn i t ng, thng th ng ch dng gi tr ny. dwMiscStatus tlib wVerMajor wVerMinor M t trong cc gi tr tr ng thi ty Gi tr GUID trong t p ODL S phin b n chnh S phin b n ph b ng trn

Ngoi ra hm UpdateRegistry() ca lp COleObjectFactory c th dng hy b ng k mt iu khin.


338

- ng k iu khin Server ng k server c thc hin bng hai hm DllRegisterServer() v DllUnregisterServer() c a ra trong tp DEF, khai bo hai hm nh sau:
STDAPI STDAPI DllRegisterServer(); DllUnregisterServer();

Trong ci t hm DllRegisterServer() chng ta phi gi hm AfxOleRegisterTypeLib() vi khai bo sau:


BOOL AfxOleRegisterTypeLib( HINSTANCE hInstance, REFGUID tlid, LPCTSTR pszFileName = NULL, LPCTSTR pszHelpDir = NULL );

v gi hm COleObjectFactoryEx::UpdateRegistryAll() c mu khai bo nh sau:


static void PASCAL COleObjectFactoryEx :: UpdateRegistryAll( );

Cc hm ny s kim tra xem kiu th vin tng ng v cc thng tin khc c ng k hay cha, nu khng c khon mc no nh vy th kiu th vin v iu khin s c ng k, ngc li s b qua. Trong ci t hm DllUnregisterServer() chng ta phi gi hai hm ngc li l AfxOleUnregisterTypeLib() c khai bo sau:
BOOL AFXAPI AfxOleUnregisterTypeLib( REFGUID tlID );

v hm COleObjectFactoryEx::UpdateRegistryAll() xc nh nu c khon mc ng k ca iu khin th s c loi b.

V d 11.1
Lp trnh to mt iu khin ActiveX cho php hin th ln ng dng khi s dng n v v l c t quc. Tp khai bo vidu01.h nh sau:

339

class CVidu01App : public COleControlModule { public: BOOL InitInstance(); int ExitInstance(); }; class CVidu01Ctrl : public COleControl { DECLARE_DYNCREATE(CVidu01Ctrl) public: CVidu01Ctrl(); public: virtual void OnDraw(CDC* pdc, const CRect& rB, const CRect& rV); protected: ~CVidu01Ctrl(); DECLARE_OLECREATE_EX(CVidu01Ctrl) DECLARE_OLETYPELIB(CVidu01Ctrl) DECLARE_OLECTLTYPE(CVidu01Ctrl) DECLARE_MESSAGE_MAP() DECLARE_DISPATCH_MAP() DECLARE_EVENT_MAP() }; extern const GUID CDECL _tlid; extern const WORD _wVerMajor; extern const WORD _wVerMinor;

Tp chng trnh vidu01.cpp l:


#include "afxctl.h" #include "Vidu01.h" #include "resource.h" IMPLEMENT_DYNCREATE(CVidu01Ctrl, COleControl) BEGIN_MESSAGE_MAP(CVidu01Ctrl, COleControl) END_MESSAGE_MAP() BEGIN_DISPATCH_MAP(CVidu01Ctrl, COleControl) END_DISPATCH_MAP() BEGIN_EVENT_MAP(CVidu01Ctrl, COleControl) END_EVENT_MAP() BEGIN_PROPPAGEIDS(CVidu01Ctrl, 1) END_PROPPAGEIDS(CVidu01Ctrl) IMPLEMENT_OLECREATE_EX(CVidu01Ctrl, "VIDU01.Vidu01Ctrl.1",

340

0xaadfa311, 0x1db0, 0x4053, 0x8a, 0xdf, 0xfc, 0xc7, 0x9e, 0xd4, 0x5, 0xb6) IMPLEMENT_OLETYPELIB(CVidu01Ctrl, _tlid, _wVerMajor, _wVerMinor) const IID BASED_CODE IID_DVidu01 = { 0x72d88209, 0x5cf7, 0x4c2c, { 0x92, 0x28, 0x87, 0x8b, 0x61, 0x6c, 0x8a, 0x71 } }; const IID BASED_CODE IID_DVidu01Events = { 0xb9e44700, 0x2b6d, 0x412e, { 0x8e, 0xc9, 0x5, 0xcc, 0x27, 0x71, 0x15, 0x81 } }; static const DWORD BASED_CODE _dwVidu01OleMisc = OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CVidu01Ctrl, IDS_VIDU01, _dwVidu01OleMisc) BOOL CVidu01Ctrl::CVidu01CtrlFactory::UpdateRegistry(BOOL bRegister) { if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_VIDU01, IDB_VIDU01, afxRegApartmentThreading, _dwVidu01OleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } CVidu01Ctrl::CVidu01Ctrl() { InitializeIIDs(&IID_DVidu01, &IID_DVidu01Events); } CVidu01Ctrl::~CVidu01Ctrl() { } void CVidu01Ctrl::OnDraw( CDC* pdc, const CRect& rB, const CRect& rV ) { double PI = 3.141592; pdc->FillRect(rB,new CBrush(RGB(255,0,0)));

341

CPen p; p.CreatePen(PS_SOLID,0,RGB(255,255,0)); pdc->SelectObject(&p); int cx,cy,x,y; double g=PI/2.0,r; cx=(rB.right-rB.left)/2; cy=(rB.bottom-rB.top)/2; r=((cx>cy)?cy:cx)*0.7; x=int(cx+r*cos(g)); y=int(cy-r*sin(g)); pdc->MoveTo(x,y); for (int i=0;i<10;i++) { g=g+2*PI/10; if (i%2==0) { x=int(cx+0.4*r*cos(g)); y=int(cy-0.4*r*sin(g)); } else { x=int(cx+r*cos(g)); y=int(cy-r*sin(g)); } pdc->LineTo(x,y); } CBrush b; b.CreateSolidBrush(RGB(255,255,0)); pdc->SelectObject(&b); pdc->FloodFill(cx,cy,RGB(255,255,0)); }

Kt qu khi kim th iu khin ActiveX nh sau:

342

11.2.5. Cng c Visual C++ to khung ActiveX


Chng ta thy vic thit lp mt b khung cho chng trnh dng ActiveX rt phc tp v mt nhiu thi gian, trong mi trng Visual C++ cho php to mt khung chng trnh kiu ActiveX rt thun tin v n gin. Tip theo chng ta c th iu chnh, thm bt cc thnh phn mong mun trong chng trnh c c mt ActiveX hon thin. Cc bc thc hin nh sau: Bc 1: To mt project ng vi chng trnh ActiveX s pht trin: Chn th t cc chc nng sau: [File] [New] chn th [Projects] chn mc [MFC ActiveX ControlWizard] g tn chng trnh vo [Project name] v chn [Ok]

Sau khi chn Ok s xut hin hp thoi xc lp cc yu t cho vic to mt ActiveX nh sau:

343

Trong [1] l s iu khin cn to trong ActiveX, [2] quy nh bn quyn (license), [3] quy nh c hng dn khi sinh m, [4] quy nh to tp tr gip. Chn [Next] s xut hin hp thoi:

344

Trong : + [Activates when visible]: iu khin s t kch hot khi hin n c hin th. + [Invisible at runtime]: i tng dng n khi thc hin. + [Avaible in "Insert Object" dialog]: iu khin s c hin th trong hp thoi chn i tng ca cc ng dng. + [Has an "About" box]: iu khin s c mt hp thoi gii thiu. + [Acts as a simple frame control]: iu khin to ra s c mt s iu khin khc v hot ng di dng mt frame. Sau chn [Finish] kt thc qu trnh to. Bc 2: iu chnh cc thnh phn trong ActiveX va to. Sau khi to xong ActiveX s c mt s thnh phn chnh c t chc di dng cy sau:

345

Trong : 1: l giao din chnh ca iu khin ActiveX s c to ra, giao din ny dng cc ng dng client tng tc vi ActiveX. 2: l giao din cc s kin c th thc hin trn ActiveX, cho php cc ng dng client s dng cc s kin yu cu ActiveX thc hin. 3: lp ng dng to ra ActiveX, c hai hm InitInstance() khi to v hm ExitInstance() gii phng ti nguyn mi ln ActiveX c s dng bi ng dng client. Lp ng dng ny k tha t lp COleControlModule. 4: lp cha iu khin ActiveX, l lp chnh to ra ActiveX. Chng ta phi xy dng cc hm thnh vin cn thit cung cp x l cho ng dng client. Lp ny k tha t lp COleControl. 5: lp cha giao din cc thuc tnh thit k i vi ActiveX, trong lp c hp thoi cha cc thnh phn nhp sa thuc tnh. Lp ny k tha t lp COlePropertyPage v chng ta c th b qua s dng lp ny. 6: hm DllRegisterServer() s thc hin ng k ActiveX vo h thng mt cch t ng. 7: hm DllUnregisterServer() s t ng hy b ng k ActiveX khi h thng khi khng cn thit s dng na. 8: cha nh danh ton cc duy nht (GUID) cho hai giao din ca ActiveX, gm nh danh giao din chnh cho ActiveX v nh danh giao din s kin cho ActiveX. 9: i tng ng dng ca ActiveX c to ra khi to mi ln ActiveX c s dng bi ng dng client. By gi chng ta c th dch v kim th ActiveX va to ra, iu chnh ActiveX ta thm bt cc thnh vin ca lp cha iu khin ActiveX mc 4 trn.

11.2.6. Cng c kim th ActiveX ca VisualC++


Sau khi xy dng thnh cng ActiveX chng ta c th kim th n bng cng c "ActiveX Control Test Container", sau y l hng dn s dng cng c kim th ActiveX.

346

Bc 1: Chn chc nng [Tools] xut hin hp thoi sau:

[ActiveX Control Test Container]

Bc 2: Chn chc nng c biu tng nh trn xc nh ActiveX cn kim th, s xut hin hp thoi chn sau:

Khi chn ActiveX cn kim th v Ok trn ca s s c iu khin tng ng vi ActiveX m chng ta chn, xem xt s hot ng ca n v c th thc hin cc phng thc, cc s kin nu cn.

347

11.3. Cc phng thc ca ActiveX


Mc nh lp iu khin c sinh ra c hm OnDraw() thc hin v ln ng dng client, hm OnResetState() khi phc trng thi ca ActiveX v hm DoPropExchange() thay i cc gi tr thuc tnh khi nhp sa thng qua hp thoi t lp cha giao din thuc tnh - phn 5.

11.3.1. Thay i hm OnDraw() v OnResetState()


Bm p chut vo tn hm cn sa s xut hin mu hm vit thm lnh, v d hm OnDraw() s c:

Hoc thay i hm OnResetState() s c:

348

11.3.2. X l thng ip hoc vit hm thnh vin


Chng ta c th thm cc thnh vin hm x l thng ip cho ActiveX theo tng bc sau: Chn chc nng [View] [Class Wizard] s xut hin hp thoi sau

Chng ta chn tn lp cha ActiveX tng ng, chn tn hm hoc thng ip cn x l trong ActiveX sau chn [Add Function]. V d chn tn thng ip WM_TIMER s xut hin hm thnh vin tng ng trong danh sch [Member functions]:

Tip theo chn chc nng [Edit Code] vit lnh cho hm thnh vin tng ng. V d chn hm OnTimer s xut hin mu sau:

349

11.3.3. Thm phng thc thng thng trong lp


Ngoi cc phng thc x l thng ip, cc phng thc vit ca lp c s, chng ta c th thm cc phng thc x l khc bng cc thao tc sau: Bm chut phi vo tn lp ActiveX s xut hin:

Chn chc nng [Add Member Function] thm mt phng thc, s c hp thoi sau:

350

Nhp tn kiu ca hm vo [Function Type] v nhp tn hm cng vi cc tham s cn thm vo [Function Declaration], chn phm vi cho hm v kiu hm v chn Ok. V d nh trn s xut hin mu hm sau:

Tip theo chng ta vit lnh cho hm x l cng vic tng ng. Ngoi ra chng ta c th thm cc thnh vin d liu lu thng tin m t v x l cn thit trong ActiveX.

V d 11.2
Lp trnh to mt iu khin ActiveX hin th ng h ca h thng khi ng dng client s dng n. Chng ta phi x l thng ip WM_TIMER trong ActiveX, khi ng chu k thi gian chng ta c th thc hin trong hm x l thng ip WM_CREATE. Cc bc thc hin l: Bc 1: To mt project kiu ActiveX theo hng dn nh trn. Bc 2: Thm hm x l thng ip WM_TIMER v WM_CREATE v vit lnh nh sau: Hm x l thng ip to ca s WM_CREATE l:

351

Hm x l thng ip thi gian WM_TIMER l:

Bc 3: Vit li hm OnDraw() hin thi gian ln iu khin ActiveX tng ng.

Kt qu sau khi dch v chy th ActiveX s nh sau:

352

11.3.4. Phng thc cho giao din ca ActiveX


Cc phng thc xt trn ch l vic trong ni b ca ActiveX, khng s dng c t ng dng client s dng ActiveX tng ng. to phng thc trong giao din ca ActiveX v c th dng bi cc ng ng client ta lm nh sau: Bc 1: Bm chut phi vo tn giao din chnh ca ActiveX.

v chn [Add Method] s xut hin:

353

Trong : + External name : tn ngoi ca phng thc, tc l tn c trong giao din ng dng client c th s dng gi phng thc. + Internal name : tn bn trong ca phng thc, l tn chnh thc. + Return type : kiu d liu tr v ca phng thc. + Parametter list : danh sch cc tham s, bao gm tn tham s v kiu ca tham s. Sau khi nhp xong chn Ok s c mt phng thc c nh ngha trong giao din chnh, mt hm thnh vin tng ng trong lp iu khin ActiveX nh sau:

Bc 2: Vit lnh cho hm ng vi phng thc c to ra. Bm p chut vo tn hm s xut hin mu vit lnh nh sau:

354

11.4. Cc s kin ca ActiveX


Tng t cc phng thc, cc s kin dnh cho ActiveX c to ra bng cng c Wizard ca VisualC++, chng ta c th chn cc s kin c trong danh sch my cung cp hoc t to mt s kin mi. S kin ca mt ActiveX s c vit m lnh m ch nh ngha giao din, n s c vit lnh bi lp trnh vin s dng trong ng dng client. Cch to mt s kin cho ActiveX nh sau: Bc 1: Bm chut phi vo giao din s kin ca ActiveX chng ta s c:

Chn chc nng [Add Event] s xut hin hp thoi nhp cc thng tin to s kin cho ActiveX sau:

Chn tn s kin my cung cp trong danh sch hoc g tn mi, nhp thm cc tham s nu c, chn Ok s c thm mt s kin trong giao din tng ng sau:

355

11.5. Cc thuc tnh ca ActiveX


Cc thuc tnh ca ActiveX c nh ngha trong giao din chnh, mi thuc tnh to ra s tng ng vi mt thnh vin d liu trong lp iu khin ActiveX. Cch to thuc tnh tng t to phng thc trn. Bc 1: Bm chut phi vo giao din chnh ca ActiveX chn [Add Property] s xut hin:

Bc 2: Trong in cc thng tin thm thuc tnh nh sau: + External name : tn thuc tnh trn giao din, s dng tng tc vi ng dng client. + Type : kiu thuc tnh. + Variable name : tn thnh vin d liu ca lp iu khin tng ng vi thuc tnh. + Notification function : hm ch bo tng ng cho thuc tnh. + Member variable : thuc tnh s l thnh vin d liu n thun.
356

- Get/Set methods : thuc tnh s c hm xc nh v thit lp gi tr. Bc 3: Vit lnh cho cc hm thnh vin tng ng vi thuc tnh c to ra, c th hm ch bo thay i gi tr thuc tnh, hm xc nh hoc thit lp gi tr cho thuc tnh.

V d 11.3
Lp trnh to mt iu khin ActiveX tng ng l mt ngi sao n cnh, mu sc v kch thc c thit lp bng thuc tnh, c cc phng thc quay v dng c th quay quanh tm ca ngi sao vi tc quay truyn vo qua tham s. Thit k iu khin ActiveX gm: - Giao din chnh: c 3 thuc tnh s cnh (SoCanh), mu sc (MauSac), kch thc (KichThuoc) v cc phng thc Quay( float tc_ ), Dung(). - Giao din s kin: khng c. - Trong lp ActiveX phi vit li hm OnDraw() v ngi sao. Sau y l s mu thit k cho ActiveX tng ng cc thuc tnh, phng thc ca giao din, thnh vin d liu, thnh vin hm ca lp iu khin. Cc bn hy vit lnh thc hin theo thit k sau:

357

11.6. S dng ActiveX


Sau khi xy dng xong cc ActiveX, dch ra tp thi hnh dng *.OCX. Nu mt ng dng client s dng ActiveX th n s t ng ng k vo h thng bi hm DllRegisterServer(). Vic s dng cc ActiveX trong cc ng dng client nh Internet Explorer, cc mi trng lp trnh khc Visual Basic, Visual Foxpro, V d s dng ActiveX trong trnh duyt Web Internet Explorer, trong trang Web bn phi dng th HTML Object theo mu sau:
<object classid = "clsid:D4061177-B2F4-4429-BD18-6E6CBBE80CC5" id = "Bai21"> <param name = "_ExtentX" value="2646"> <param name = "_ExtentY" value="1323"> <param name = "_StockProps" value="0"> </object>

Trong classid l nh danh ca i tng lp ng vi ActiveX c s dng, s hiu ny chnh l gi tr nh danh duy nht c s dng xy dng ActiveX tng ng - GUID. Kt qu trn Web s xut hin i tng ca ActiveX v hot ng nh sau:

C th s dng ActiveX vo trong ngn ng VB theo cch sau: trn mi trng VB chn Project Components xut hin hp thoi:

358

nh du vo mc ng vi ActiveX ng k chn Ok, s xut hin trn thanh cng c biu tng ca ActiveX sau:

Tip theo bn chn biu tng v v ln Form i tng ca ActiveX tng ng, kt qu s c:

Trn y l v d s dng ActiveX vo cc ng dng client, bn c c th ng dng n vo bt k mi trng no c h tr ActiveX Container. Ngoi ra bn c c th thay i cc ActiveX ca v d trn cho ph hp hoc t xy dng cc ActiveX mi ty .
359

11.7. Bi tp
Bi tp 11.1
Hy dng cng c Wizard ca Visual C++ to mt ActiveX, sau thm cc thnh phn ActiveX hot ng nh mt ng h c 3 kim: kim giy, kim pht v kim gi.

Bi tp 11.2
To mt ActiveX c mt qu bng chuyn ng v phn x tr li trong vng ca s ca ActiveX.

Bi tp 11.3
To mt ActiveX c cc hnh elp ng tm v thay i m theo th t to cm gic ca gn sng.

Bi tp 11.4
To mt ActiveX m phng dao ng tt dn ca con lc n.

360

TI LIU THAM KHO


Ting Anh [1] [2] [3] [4] Ting Vit [5] [6] Lp trnh Windows bng Visual C++, ng Vn c, L Quc Hng, NXB Gio dc, 2001. C++ v lp trnh hng i tng, Phm Vn t, NXB Khoa hc v K thut, 2000. MFC Programming from the Ground Up, Herbert Schildt, Tata McGraw-Hill Publishing Company Limited, 2000. Programming Microsoft Visual C++, David J. Kruglinski, George Sepherd v Scott Wingo. Microsoft Developer Network Library Edition, CDs-ROM, 2000-2004. Resoures on Googles Search Engine, Internet.

361

You might also like