Professional Documents
Culture Documents
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.
Tc gi
- 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.
- 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, ...
- 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
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.
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.
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>
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)
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( ); };
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
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 : + 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
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
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
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.
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
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; }
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 );
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
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
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.
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.
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); }
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:
41
CPoint pt ); CPoint pt );
CPoint pt ); 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; }
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( );
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); }
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.
48
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
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
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
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:
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 ); }
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
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
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;
68
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 );
+ 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
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 );
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
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.
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
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().
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
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 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
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
DIALOG
[ty-chn]
X, Y, Width, Height
tiu--hp-thoi kiu-hp-thoi
nh-ngha-cc-iu-khin-trn-hp-thoi }
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();
88
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
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
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:
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
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
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.
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
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
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
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);
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
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
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
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
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
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
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
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:
107
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); }
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 )
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
- 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,...
117
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( );
4.3.2. Mt s lnh v c bn
- V mt im nh
COLORREF CDC::SetPixel( int x, int y, COLORREF crColor );
118
- 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:
119
- 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
122
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:
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 );
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
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
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
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
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 );
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
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 );
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
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
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
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 );
147
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 );
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 );
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.
149
char tmFirstChar; char tmLastChar; char tmDefaultChar; char tmBreakChar; BYTE tmItalic; BYTE tmUnderlined; BYTE tmStruckOut; BYTE tmPitchAndFamily; BYTE tmCharSet; } TEXTMETRIC;
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
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.
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
+ 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
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
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
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 );
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:
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
175
Rebar Rich Edit Status Tab Toolbar Tooltip Trackbar Tree View Up-down(spin)
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
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
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)
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
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.
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;
179
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.
Lnh n nt lnh:
180
BOOL
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:
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
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 {
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
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 );
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.
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
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.
- 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
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
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:
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
Thang chia n m pha tri Thang chia n m pha ph i Thang chia n m c hai pha
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
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
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 )
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( );
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:
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
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.
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:
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
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;
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 );
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
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
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
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;
LPARAM } TVITEM;
214
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
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.
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
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(); }
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
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
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 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:
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
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.
232
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.
234
dng
macro
DECLARE_DYNCREATE y l phm vi private, tuy nhin bn c th t n phm vi protected hoc pubic nu cn.
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
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 )
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
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.
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
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
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
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.
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.
Tham s bModified bng TRUE nu mun t c thay i ti liu, ngc li t bng FALSE.
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
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
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() };
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
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
- 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
- i tn tp
static void Rename( LPCTSTR OldName, LPCTSTR NewName );
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
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( );
- 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
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( );
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
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
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.
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.
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.
272
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
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
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() };
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
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
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
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.
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,
UINT
DWORD
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.
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
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
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
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;
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
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.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
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 );
303
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
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
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.
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.
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.
DESCRIPTION ' m t th vin ' EXPORTS ; Cc nh ngha thnh phn giao din y
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
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;
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)); }
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
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
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
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); }
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
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.
327
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.
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
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:
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
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
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
- 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();
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 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;
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)); }
342
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.
346
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
348
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
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
352
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
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
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
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
361