Kinh doanh nhà đất trên mạng Client/Server

Tài liệu Kinh doanh nhà đất trên mạng Client/Server: ... Ebook Kinh doanh nhà đất trên mạng Client/Server

doc130 trang | Chia sẻ: huyen82 | Lượt xem: 1425 | Lượt tải: 0download
Tóm tắt tài liệu Kinh doanh nhà đất trên mạng Client/Server, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Giôùi thieäu Thread trong Delphi Thread laø gì? Tính naêng Thread cho pheùp moät chöông trình xöû lyù ñoàng thôøi nhieàu coâng vieäc. Chaúng haïn trong chöông trình Go!Zilla Ver 3.2 Copyright Ó 1997-98 Gizmonet, moät luùc coù theå download nhieàu file töø cuøng hoaëc nhieàu website khaùc nhau. Noù coøn cho ngöôøi duøng ñònh ñoä öu tieân cho töøng thread. Baïn coù theå duøng BorlandC, Delphi, Cbuilder, Visual C ... ñeå vieát neân nhöõng chöông trình coù tính naêng thread. Nhöng duø baïn laäp trình baèng ngoân ngöõ naøo ñi chaêng nöõa, thì cuõng phaûi söû duïng nhöõng haøm API cuûa Microsoft cung caáp nhö CreateThread, SetThreadPriority ... moät caùch tröïc tieáp hoaëc giaùn tieáp. ÖÙng duïng cuûa Thread Thread ñöôïc söû duïng raát nhieàu treân caùc lónh vöïc nhö ñoà hoïa (xöû lyù nhieàu hình aûnh moät luùc), trong troø chôi (laøm neàn hoaëc moãi nhaân vaät trong troø chôi laø moät thread), truyeàn tin (tín hieäu xuaát ra ñöôïc xöû lyù töùc thôøi) ... Thread laøm cho chöông trình trôû neân ñôn giaûn, deã hieåu khi ta phaûi vieát nhöõng chöông trình ñoøi hoûi xöû lyù ñoàng thôøi nhieàu coâng vieäc. Söû duïng TThread trong Delphi Söû duïng TThread cuûa Delphi ñeå vieát neân nhöõng chöông trình coù tính naêng Thread thì raát deã. Caáu truùc cô baûn moät unit coù söû duïng Thread nhö sau : unit Unit1; interface uses Classes; type TMyThread = class(TThread) private { Private declarations } protected procedure Execute; override; end; implementation { TMyThread } procedure TMyThread.Execute; begin { phaàn maõ coù tính naêng Thread ñaët ôû ñaây} end; end. Moät ñieàu quan troïng caàn löu yù khi vieát Thread laø nhöõng ñoái töôïng hay haøm naøo naèm trong thö vieän VCL cuûa Delphi phaûi goïi baèng phöông phaùp Synchronize. Ví duï : Synchronize(UpdateCaption); Vôùi UpdateCaption : procedure TMyThread.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; Caùc method ñaùng chuù yù khi vieát Thread * Constructor Create(CreateSuspended: Boolean); Constructor Create ñeå khôûi taïo moät ñoái töôïng Thread. Neáu CreateSuspended = False, Execute ñöôïc goïi ngay laäp töùc Neàu CreateSuspended = True, Execute khoâng ñöôïc goïi cho ñeán khi Resume ñöôïc goïi. * Destructor Destroy; override; Destructor Destroy huûy ñoái töôïng thread vaø giaûi phoùng boä nhôù noù chieám giöõ. * Procedure DoTerminate; virtual; DoTerminate laøm cho thread goïi söï kieän OnTerminate. * Procedure Execute; virtual; abstract; Procedure Execute laø moät method abstract phaûi ñöôïc override bôûi lôùp con. Noù chöùa maõ khi baét ñaàu Thread. * Procedure Resume; Procedure Resume tieáp tuïc goïi moät thread taïm ngöng. * Procedure Suspend; Procedure Suspend taïm ngöng moät thread ñang chaïy. * Procedure Synchronize(Method: TThreadMethod); Procedure Synchronize thöïc hieän method duøng thö vieän VCL. * Procedure Terminate; Procedure Terminate ra hieäu cho thread döøng baèng caùch gaùn property Terminated laø True. Caùc property ñaùng chuù yù khi vieát Thread * property FreeOnTerminate: Boolean; property FreeOnTerminate ñònh cho ñoái töôïng thread töï ñoäng giaûi phoùng nhôù neáu FreeOnTerminate = True. * property Handle: Thandle; property Handle laø handle cuûa thread. * property Priority: TThreadPriority; property Priority xaùc ñònh ñoä öu tieân giöõa caùc thread khaùc trong tieán trình. TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical); + tpIdle : Chæ thöïc hieän khi heä thoáng Windows raûnh roãi, noù khoâng ngaét ngang ñoái töôïng thread khaùc ñeå chaïy. + tpLowest : Möùc ñoä öu tieân döôùi 2 ñieåm so vôùi bình thöôøng. + tpLower : Möùc ñoä öu tieân döôùi 1 ñieåm so vôùi bình thöôøng. + tpNormal: Möùc ñoä öu tieân bình thöôøng. + tpHigher : Möùc ñoä öu tieân treân 1 ñieåm so vôùi bình thöôøng. + tpHigher : Möùc ñoä öu tieân treân 1 ñieåm so vôùi bình thöôøng. + tpHighest : Möùc ñoä öu tieân treân 2 ñieåm so vôùi bình thöôøng. + tpTimeCritical : Möùc ñoä öu tieân cao nhaát. * property Suspended: Boolean; property Suspended chæ ñònh thread taïm ngöng neáu baèng true. * property Terminated: Boolean; property Terminated chæ ñònh raèng thread yeâu caàu döøng neáu baèng true. * property ThreadID: THandle; property ThreadID nhaän bieát duy nhaát cho ñoái töôïng thread xuyeân suoát heä thoáng. ThreadID thì khaùc property Handle. Tranh chaáp döõ lieäu khi vieát multi-thread Khi baïn vieát moät chöông trình multi-threaded, coù tröôøng hôïp 2 thread cuøng truy caäp ñeán moät vuøng döõ lieäu, chaúng haïn nhö laø moät file, ñieàu naøy coù theå laøm cho file bò hö hoaëc coù theå maùy cuûa baïn seõ bò treo. Ñeå giaûi quyeát vaán ñeà naøy, baïn seõ cho caùc thread khaùc khoâng theå truy caäp ñeán vuøng nhôù maø thread hieän haønh ñang söûa ñoåi döõ lieäu cho ñeán khi döõ lieäu ñöôïc xöû lyù xong. Critical sections ñöôïc thieát keá maø moät phaàn resource ñöôïc duøng rieâng bieät vaø taùch rôøi khoûi caùc tieán trình khaùc. Baïn haõy töôûng töôïng raèng coù hai ngöôøi cuøng ñi song song treân moät con ñöôøng, boãng nhieân xuaát hieän moät caây caàu heïp, chæ ñuû ñeå moät ngöôøi ñi qua. Bình thöôøng moät ngöôøi seõ nhöôøng ñöôøng cho ngöôøi kia ñi tröôùc. Khi maø moät ngöôøi qua caàu roài thì ngöôøi kia seõ tieáp tuïc ñi qua caàu vaø hoï laïi tieáp tuïc ñi song song vôùi nhau. Critical sections cuõng töông töï nhö vieäc ñi qua caàu. Baïn haõy nhìn hình ôû treân ñaây, hai thread (muõi teân maøu cyan) ñang chaïy treân tieán trình ñôn (vuøng maøu ñen), khi caùc thread chaïy ñeán critical sections (vuøng maøu xanh döông), moät thread seõ nhöôøng cho thread kia ñi qua. Trong thöïc teá, moät thread seõ ñi ñeán critical sections, noù coù theå taïo ra moät côø ra hieäu cho caùc thread khaùc khoâng ñöôïc lieân laïc vôùi data. Ñeå thöïc hieän critacal sections trong maõ chöông trình vieát baèng Borland Delphi, baïn haõy laøm daáu khoái treân moãi thread maø truy caäp ñeán vuøng nhôù chung baèng caùc haøm EnterCriticalSection vaø LeaveCriticalSection. Ñieàu ñaàu tieân, trong chöông trình, baïn phaûi ñònh nghóa moät critical treân boä nhôù. Ñieàu naøy thöïc hieän ñöôïc baèng caùch goïi haøm InitializeCriticalSection. Haøm naøy ñöôïc khai baùo nhö sau: procedure InitializeCriticalSection(var lpCriticalSection: TRTLCriticalSection); stdcall; InitializeCriticalSection laáy moät tham soá kieåu TRTLCriticalSection, maø tröôøng cuûa noù löu tröõ thoâng tin veà critical section. Baïn khoâng caàn quan taâm veà caáu truùc cuûa noù, bôûi bì chaúng caàn thao taùc treân ñoù. Haõy khai baùo moät bieán toaøn cuïc kieåu TRTLCriticalSection. Sau khi laøm critical xong, haõy huûy noù baèng haøm DeleteCriticalSection. Cuõng gioáng nhö InitializeCriticalSection, haøm naøy coù moät tham soá kieåu TRTLCriticalSeciont. Trong tröôøng hôïp naøy, hai tham soá bieán trong DeleteCriticalSection vaø InitializeCriticalSection laø moät. Trong chöông trình baïn haõy goõ vaøo caùc leänh sau: unit myCritical; Interface var CritSect : TRTLCriticalSection; … Implementation … initialization InitializeCriticalSection(CritSect); finalization DeleteCriticalSection(CritSect); end. Söû Duïng Critical Section trong chöông trình Ñaët critical section ñeå duøng trong thread thì raát deã. Baïn chæ caàn xem moät ñoaïn maõ ví duï döôùi ñaây thì seõ bieát ngay: procedure TMyThread.ChangeData; begin ... EnterCriticalSection(CritSect); ...Caùc thao taùc söûa ñoåi döõ lieäu duøng chung ñaët ôû ñaây LeaveCriticalSection(CritSect); end; Giao tieáp giöõa caùc maùy moâ hình Client/Server Trong ñeà taøi thöïc taäp naøy, ta duøng ngoân ngöõ laäp trình Delphi ñeå giao tieáp giöõa caùc maùy qua moâ hình Client/Server, cuï theå laø söû duïng caùc control nhö : TClientSocket, ClientWinSocket, TServerSocket, TServerWinSocket. Hình döôùi ñaây lieät keâ caùc lôùp cuûa socket control: TClientSocket TClientSocket ñöôïc duøng ñeå keát noái ñeán moät Server Socket. Ñeå söû duïng control naøy, baïn neân laøm caùc thao taùc sau ñaây: Vieát maõ cho OnRead Event Ñònh Address property ñeán Server address. Ñònh Port laø giaù trò Port Property cuûa TServerSocket muoán keát noái. Ñònh ClientType property ñeán ctNonBlocking. Goïi Open method ñeå keát noái ñeán remote Server. Ta noùi theâm veà ClientType property. Neáu ClientType = ctNonBlocking, khi chöông trình ñoïc hay ghi döõ lieäu ñeán socket, chöông trình seõ thöïc hieän leänh I/O naøy roài tieáp tuïc thöïc hieän chöông trình ngay caû thao taùc I/O naøy chöa thöïc hieän xong. Neáu ClientType = ctBlocking, chöông trình seõ taïm khoâng chaïy tieáp maø chôø cho ñeán khi thao taùc I/O thöïc hieän xong. Trong chöông trình naøy, ta seõ cho ClientType = ctNonBlocking. Ghi döõ lieäu ñeán server Khi baïn muoán göûi döõ lieäu ñi, duøng leänh töông töï nhö sau: MyClientSocket.Socket.SendText("this is a test"); TClientSocket TClientWinSocket Hoaëc duøng leänh: BytesWritten := MyClientSocket.Socket.SendBuf(buf, count); Ñoïc döõ lieäu töø server Baïn coù theå ñoïc döõ lieäu töø Server baèng caùch duøng leänh ReceiveText hay ReceiveBuf ñaët trong OnRead Event. procedure TChatForm.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); begin StringData := Socket.ReceiveText; end; TClientWinSocket Ta seõ moâ taû moät soá haøm quan troïng trong TClientWinSocket. function ReceiveBuf(var Buf; Count: Integer): Integer; ReceiveBuf ñoïc döõ lieäu töø server socket, soá byte ñoïc do ngöôøi duøng ñònh. Döõ lieäu ñoïc ñöôïc seõ chöùa trong Buf, giaù trò traû veà laø soá byte ñaõ thöïc söï ñoïc ñöôïc. function ReceiveText: string; Duøng ReceiveText ñeå ñoïc moät chuoãi töø server socket. function SendBuf(var Buf; Count: Integer): Integer; Duøng SendBuf ñeå truyeàn döõ lieäu trong Buf ñeán server socket. Haøm naøy traû veà soá byte thöïc söï ñaõ truyeàn. procedure SendText(const S: string); Duøng SendText ñeå truyeàn moät chuoãi ñeán server socket. function SendStream(AStream: TStream): Boolean; Duøng SendStream ñeå truyeàn taát caû thoâng tin trong AStream ñeán server socket. Haøm naøy traû veà true neáu döõ lieäu ñaõ thöïc söï truyeàn ñi. Baïn khoâng caàn phaûi giaûi phoùng boä nhôù cho AStream, windows socket seõ giaûi phoùng noù cho baïn. function SendStreamThenDrop(AStream: TStream): Boolean; SendStreamThenDrop laøm vieäc gioáng nhö SendStream, nhöng khi thi haønh xong leänh naøy, noù seõ töï ñoäng terminates. procedure Lock; Goïi Lock tröôùc khi baét ñaàu ñoaïn maõ khoâng thread-safe. Baïn ñöøng duøng Lock khi thöïc hieän ñoaïn maõ nhö ñoïc vaø ghi leân blocking connection bôûi vì neáu duøng seõ thöøa. Vôùi ClientType laø ctBlocking, chöông trình ñaõ töï ñoäng taïm ngöng cho ñeán khi caùc thao taùc I/O thöïc hieän xong. procedure UnLock; Goïi UnLock ôû cuoái ñoaïn maõ khoâng thread-safe maø tröôùc ñoù ñaõ duøng leänh Lock, khi aáy caùc thread khaùc laïi tieáp tuïc thi haønh tieáp. TserverSocket TServerSocket ñieàu khieån server socket connections trong TCP/IP server. TServerSocket seõ thieát laäp keát noái vôùi moät maùy khaùc khi maùy naøy ra yeâu caàu. Server socket coù theå keát noái ñeán moät soá client vaø baïn coù theå giao tieáp vôùi caùc client naøy. Truyeàn döõ lieäu ñeán moät Client MyServer.Socket.Connections[2].SendText("this is a test"); TServerSocket TServerWinSocket TCustomWinSocket[array] Caâu leänh ôû treân göûi döõ lieäu ñeán client thöù 3. Ñoïc döõ lieäu töø moät client Ñeå ñoïc döõ lieäu töø moät Client, baïn haõy ñoùn söï kieän OnClientRead. Baïn coù theå ghi leänh trong event OnClientRead nhö sau: procedure TChatForm.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); var Data : string; begin Data := Socket.Receive; ShowMessage(‘Data sent : ‘ + Data); end; Baïn coù theå bieát chính xaùc Client thöù maáy ñaõ göûi döõ lieäu ñeán server socket Ñoaïn maõ sau ñaây seõ cho bieát client naøo ñaõ göûi döõ lieäu ñeán server socket: procedure TChatForm.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); var Data : string; Client, Total : integer; begin Total := MyServer.Socket.ActiveConnections; for Client := 0 to Total do if (MyServer.Socket.Connections[Client] = Socket then Break; Data := Socket.Receive; ShowMessage(‘Data sent from client[‘ + IntToStr(Client) + ‘] : ‘ + Data); end; TServerWinSocket Hai nhieäm vuï chính cuûa TServerWinSocket laø: Laéng nghe yeâu caàu keát noái cuûa Client TServerWinsocket luoân laéng nghe yeâu caàu keát noái töø client. Khi coù moät yeâu caàu keát noái göûi tôùi, TServerWinSocket seõ taïo ra moät socket control môùi (kieåu TServerWinSocket) ñeå lieân laïc vôùi client ñoù. socket control môùi naøy seõ ñöôïc theâm vaøo moät danh saùch ñöôïc moâ taû döôùi ñaây. Coâng vieäc naøy laø hoaøn toaøn töï ñoäng, ngöôøi laäp trình khoâng caàn quan taâm. Quaûn lyù daõy caùc client socket ñaõ keát noái vôùi server socket Ñeå lieân laïc vôùi moät client, baïn phaûi choïn moät socket trong danh saùch caùc client, sau ñoù baïn coù theå thöïc hieän caùc thao taùc ñoïc ghi cho client naøy. Baïn coù theå duøng ActiveConnections property ñeå giao tieáp vôùi taát caû caùc client. var TotalClients, x : integer; begin TotalClients := MyServer.Socket.ActiveConnections; for x := 0 to TotalClients do MyServer.Socket.Connections[x].SendText("testing..."); end; TServerClientWinSocket TServerClientWinSocket gioáng nhö TClientWinSocket, caû hai ñeàu laø con cuûa TCustomWinSocket. Söï khaùc nhau giöõa TClientWinSocket vaø TServerClientWinSocket laø TClientWinSocket lieân laïc vôùi Server socket coøn TServerClientWinSocket lieân laïc vôùi moät client naøo ñoù. Giôùi thieäu chöông trình Noäi dung vaø yù nghóa chöông trình Chöông trình ñöôïc xaây döïng treân moâ hình client/server cho pheùp nhieàu client cuøng truy caäp ñeán döõ lieäu naèm treân maùy server. Chöông trình ñöôïc duøng bôûi 3 nhoùm ñoái töôïng laø khaùch haøng, ngöôøi caäp nhaät döõ lieäu veà nhaø cöûa treân maùy server vaø ngöôøi quaûn lyù. Neáu laø maùy server, treân maùy baïn phaûi coù taát caû caùc taäp tin döõ lieäu cuûa chöông trình thì môùi ñöôïc. Neáu laø khaùch haøng hoaëc ngöôøi caäp nhaät döõ lieäu, baïn chæ caàn moät chöông trình thöïc thi laø ñuû. Coù theå baïn cuõng chaúng caàn phaûi cheùp chöông trình veà maùy mình laøm gì maø thöïc thi noù baèng caùch attach ñeán maùy server ñeå thöïc thi chöông trình. Baát kyø ngöôøi duøng naøo muoán truy caäp ñeán chöông trình caàn phaûi ñöôïc ñaêng kyù moät username, password vaø quyeàn söû duïng. Khi chöông trình ñöôïc thöïc thi, moät khung trao ñoåi hieän ra nhö sau: * Neáu laø khaùch haøng, baïn phaûi nhaäp caùc tham soá sau: + HostName : Teân Computer cuûa maùy server. + User Name: Teân ñaêng kyù. + Password : Maät maõ ñaõ ñaêng kyù. + Level : Choïn Khaùch Haøng Khi khaùch haøng yeâu caàu moät vieäc chaúng haïn ñaêng kyù thueâ moät caên nhaø, chöông trình (client) seõ göûi moät thoâng ñieäp thueâ nhaø ñeán maùy server. Maùy server seõ nhaän ñöôïc yeâu caàu naøy vaø taïo ra moät thread môùi ñeå giaûi quyeát coâng vieäc ñaêng kyù thueâ nhaø cho client. Taát nhieân vieäc tranh chaáp döõ lieäu phaûi ñöôïc ñeà caäp khi thöïc hieän thao taùc treân. Sau khi thöïc hieän xong, chöông trình server seõ göûi traû keát quaû veà cho maùy client. Ngöôøi khaùch haøng coù theå thöïc hieän caùc coâng vieäc nhö sau: + Xem thoâng tin veà moät caên nhaø + Lieät keâ caùc caên nhaø thoûa moät soá ñieàu kieän do khaùch haøng ñònh nhö: Nhaø laø thueâ hay baùn; Nhaø noäi hay ngoaïi thaønh; Giaù tieàn nhoû nhaát vaø lôùn nhaát trong khoaûng naøo; Dieän tích nhaø nhoû nhaát vaø lôùn nhaát laø bao nhieâu. + Ñaêng kyù thueâ moät caên nhaø. + Ñaêng kyù mua moät caên nhaø. * Neáu laø ngöôøi caäp nhaät töø ñieån döõ lieäu nhaø, baïn phaûi nhaäp caùc tham soá sau: + HostName : Teân Computer cuûa maùy server. + User Name: Teân ñaêng kyù. + Password : Maät maõ ñaõ ñaêng kyù. + Level : Choïn Ngöôøi Caäp Nhaät Thoâng Tin Khi ngöôøi caäp nhaät döõ lieäu yeâu caàu moät vieäc chaúng haïn theâm moät thoâng tin nhaø môùi, chöông trình (client) seõ göûi moät thoâng ñieäp theâm thoâng tin nhaø môùi ñeán maùy server. Chöông trình server seõ nhaän ñöôïc yeâu caàu naøy vaø taïo ra moät thread ñeå giaûi quyeát coâng vieäc theâm thoâng tin nhaø môùi cho client. Taát nhieân vieäc tranh chaáp döõ lieäu phaûi ñöôïc ñeà caäp khi thöïc hieän thao taùc treân. Sau khi thöïc hieän xong, noù seõ göûi traû keát quaû veà cho maùy client. Ngöôøi caäp nhaät döõ lieäu coù theå laøm caùc thao taùc sau: + Xem thoâng tin veà moät caên nhaø + Lieät keâ caùc caên nhaø thoûa moät soá ñieàu kieän do khaùch haøng ñònh nhö: Nhaø laø thueâ hay baùn; Nhaø noäi hay ngoaïi thaønh; Giaù tieàn nhoû nhaát vaø lôùn nhaát trong khoaûng naøo; Dieän tích nhaø nhoû nhaát vaø lôùn nhaát laø bao nhieâu. + Theâm thoâng tin veà moät caên nhaø môùi. + Söûa ñoåi thoâng tin moät caên nhaø ñaõ coù roài. + Bôùt thoâng tin veà moät caên nhaø khoûi töø ñieån. * Neáu laø ngöôøi quaûn lyù (server), baïn phaûi nhaäp caùc tham soá sau: + User Name: Teân ñaêng kyù. + Password : Maät maõ ñaõ ñaêng kyù. + Level : Choïn Ngöôøi Quaûn Lyù Caùc taäp tin döõ lieäu ñeàu naèm treân maùy server. Caùc client khoâng theå truy caäp tröïc tieáp ñeán döõ lieäu ñöôïc maø chæ göûi yeâu caàu ñeán cho server thöïc hieän. Khi Server nhaän ñöôïc moät yeâu caàu naøo ñoù töø client, noù seõ taïo ra moät thread môùi ñeå giaûi quyeát cho vaán ñeà naøy. Neáu döõ lieäu bò thay ñoåi, chöông trình seõ phaûi caäp nhaät thoâng tin ngay treân maøn hình cuûa toaøn boä caùc maùy client. Ngöôøi quaûn lyù coù theå laøm caùc thao taùc sau: + Xem thoâng tin veà moät caên nhaø + Lieät keâ caùc caên nhaø thoûa moät soá ñieàu kieän do khaùch haøng ñònh nhö: Nhaø laø thueâ hay baùn; Nhaø noäi hay ngoaïi thaønh; Giaù tieàn nhoû nhaát vaø lôùn nhaát trong khoaûng naøo; Dieän tích nhaø nhoû nhaát vaø lôùn nhaát laø bao nhieâu. + Theâm thoâng tin veà moät caên nhaø môùi. + Söûa ñoåi thoâng tin moät caên nhaø ñaõ coù roài. + Bôùt thoâng tin veà moät caên nhaø khoûi töø ñieån. + Thoáng keâ caùc caên nhaø ñaõ cho thueâ. Chöông trình lieät keâ danh saùch caùc nhaø ñaõ cho thueâ keøm theo moïi thoâng tin veà caùc nhaø ñaõ thueâ naøy. + Ngöôøi quaûn lyù coù theå xem nhaø naøo ñaõ heát haïn cho thueâ ñeå ñöa nhaø naøy trôû veà danh saùch nhaø coù theå cho thueâ. + Thoáng keâ caùc caên nhaø ñaõ baùn. Ngöôøi quaûn lyù coù theå xem danh saùch taát caû caùc nhaø ñaõ baùn vaø caû moïi thoâng tin veà noù nöõa. YÙ nghóa chính trong chöông trình naøy laø nhaèm giaûi quyeát ba vaán ñeà chính sau ñaây: Duøng thread ñeå phaân chia thôøi gian thöïc hieän coâng vieäc cuûa töøng client. Ví duï moät client naøo ñoù yeâu caàu ñeán server moät taùc vuï maø ñoøi hoûi moät thôøi gian laâu môùi giaûi quyeát xong. Neáu khoâng phaân chia thôøi gian thì trong luùc thöïc hieän taùc vuï naøy cho client ñoù, caùc client khaùc khoâng theå ra leänh ñöôïc cho maùy server, chöông trình chaïy khoâng toát. (2) Giaûi quyeát tranh chaáp ñeå baûo toaøn döõ lieäu. Neáu cuøng moät luùc, hai hay nhieàu client cuøng ñoøi quyeàn söûa chöõa thoâng tin veà nhaø cöûa, neáu khoâng tính ñeán vieäc naøy, döõ lieäu coù nguy cô bò hö hoûng. Ñaây laø moät chöông trình öùng duïng thöïc söï vì noù coù haàu heát caùc tính naêng cuûa moät chöông trình kinh doanh nhaø ñaát treân maïng client/server. Phaàn tieáp theo ta seõ noùi chi tieát veà toå chöùc döõ lieäu cuûa chöông trình, thoâng tin veà nhaø cöûa, caùch giao tieáp giöõa caùc maùy, tranh chaáp döõ lieäu, phaân chia CPU cho client… Caùc vaán ñeà chính caàn giaûi quyeát Toå chöùc döõ lieäu trong chöông trình Thoâng tin veà nhaø cöûa goàm coù: THomeInfo = packed record TenNha : string[30]; // Teân nhaø CapNha : byte; // Caáp nhaø ChieuDai : real // Chieàu daøi nhaø ChieuRong : real; // Chieàu roäng nhaø TangLau : byte; // Soá laàu PhongKhach : byte; // Soá phoøng khaùch PhongNgu : byte; // Soá phoøng nguû PhongTam : byte; // Soá phoøng taém DiaChi, // Ñòa chæ nhaø Duong, // Teân ñöôøng ThanhPho : string[30]; // Teân thaønh phoá Quan : string[30]; // Teân quaän NhaChoThue : boolean; // Coù phaûi nhaø cho thueâ GiaMoiThang : real; // Giaù tieàn thueâ moãi thaùng NhaBan : boolean; // Coù phaûi nhaø muoán baùn TriGia : real; // Giaù tieàn baùn NhaNgoaiThanh : boolean; // Nha ngoaïi oâ hay noäi thaønh CoNuocMay : Boolean; // Nhaø coù nöôùc maùy khoâng NhaCoHeThongNuocNong : Boolean; // Nhaø heä thoáng nöôùc noùng NhaCoHoBoi : boolean; // Nhaø coù hoà bôi khoâng NhaCoNuocGieng : boolean; // Nhaø coù nuôùc gieáng NhaTrongHem : boolean; // Nhaø trong heûm hay khoâng ChieuRongHem : real; // Chieàu roäng heûm VaoHemBaosau : real; // Chieàu saâu heûm NamXayDung : TDateTime; // Naêm xaây döïng nhaø TinhTrangNha : Byte; // Tình traïng nhaø: Raát Toát= 0,Toát = 1 // Trung bình = 2, Keùm = 3 TrangTriNoiThat : Byte; // Sang troïng = 0, Toát = 1 // Trung bình = 2, Keùm = 3 NhaCoVuon : boolean; // Nhaø coù vöôøn khoâng ChieuRongVuon : real; // Chieàu roäng vöôøn tính theo m HuongNha : Byte; // Höôùng nhaø (Ñoâng = 0, Taây = 1, ChuQuyen : Byte; // Nam = 2, Baéc = 3, Ñoâng Baéc = 4, // Ñoâng Nam = 5, Taây Baéc = 6 // Taây Nam = 7 DienTich : real; // Dieän tích nhaø (m vuoâng) rent_roi : boolean; // Nhaø ñaõ thueâ roài sell_roi : boolean; // Nhaø ñaõ baùn roài NgayDauThue : TDateTime; // Ngaøy baét ñaàu thueâ nhaø NgayCuoiThue : TDateTime; // Ngaøy keát thuùc thueâ nhaø end; Caùc taäp tin döõ lieäu trong chöông trình goàm coù: ltdata.dic : file of THomeInfo, chöùa thoâng tin nhaø cöûa ltidx.dic : file of longint, index file ltrent.dic : file of longint, löu index caùc nhaø ñaõ cho thueâ ltsell.dic : file of longint, löu index caùc nhaø ñaõ baùn Keát noái cho client Ta keát noái cho moät client baèng ñoaïn maõ sau: with ClientSocket do begin Host := DomainName; Active := True; end; Tuøy vaøo quyeàn ñaõ ñaêng kyù cuûa ngöôøi söû duïng, chöông trình seõ hieän leân khung trao ñoåi töông öùng. Chaúng haïn, neáu quyeàn söû duïng laø khaùch haøng, chöông trình chæ hieän ra caùc chöùc naêng cho pheùp hoï tìm kieám, ñaêng kyù thueâ mua nhaø… nhöng khoâng hieän ra caùc chöùc naêng söûa ñoåi döõ lieäu. Huûy keát noái cho client Ta huûy keát noái cho moät client baèng ñoaïn maõ sau: ClientSocket.Close; Tranh chaáp döõ lieäu Ñeå traùnh döõ lieäu coù theå bò hö hoûng khi nhieàu client cuøng söûa ñoåi döõ lieäu naèm treân maùy server, chöông trình ñaõ giaûi quyeát ñöôïïc vaán ñeà naøy baèng caùch söû duïng caùc haøm API cuûa windows, xin xem phaàn 1.3 cuûa baøi baùo caùo naøy. Duøng thread ñeå phaân chia CPU cho caùc thao taùc cuûa client Ñeå trong cuøng moät thôøi gian, nhieàu client coù theå truy caäp ñeán cuøng moät döõ lieäu naèm treân maùy server, ta duøng thread. Xin xem phaàn 1 cuûa baøi baùo caùo naøy ñeå bieát caùch duøng thread. Baïn cuõng coù theå xem Ñoà AÙn Moân Hoïc – Thread trong Delphi cuûa Leâ Tuaán, KS2K6 ñeå hieåu roõ hôn veà thread, trong naøy cuõng coù source minh hoïa cho thread. Caùc chöùc naêng cho ngöôøi quaûn lyù Ñaây laø khung trao ñoåi chính cuûa chöông trình: Chöông trình cung caáp cho baïn haàu heát caùc tính naêng cuûa moät trình quaûn lyù döõ lieäu thoâng thöôøng. Caùc thao taùc treân döõ lieäu thöïc chaát ñeàu do chöông trình server ñaûm nhaän. Tìm kieám moät nhaø Toaøn boä nhaø coù trong töø ñieån (khoâng keå nhaø ñaõ thueâ hay baùn) seõ ñöôïc lieät keâ trong moät listbox. Danh saùch nhaø naøy ñöôïc saép xeáp theo alphabet theo teân gôïi nhôù cuûa nhaø. Chöông trình cho baïn moät oâ soaïn thaûo ñeå goõ teân nhaø caàn tìm vaøo, khi goõ ñeán ñaâu, chöông trình töï ñoäng nhaûy ñeán teân nhaø gaàn gioáng vôùi teân baïn goõ vaøo nhaát. Giaûi thuaät laäp trình cho Tìm kieám nhaø O soaïn thaûo TEdit ñoùn söï kieän OnChange, moãi khi coù söï thay ñoåi, chöông trình seõ taïo moät thread teân THomeSearchTextThread. procedure THomeSearchTextThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; Haøm DoThread naøy chuû yeáu goïi haøm HomeSearch ñöôïc moâ taû döôùi ñaây: function HomeSearch (TeânNhaø : string; var found : boolean) : longint; Haøm naøy tìm kieám trong danh saùch nhaø coù TeânNhaø nhö tham soá ñöa vaøo khoâng? Input : TeânNhaø : Teân nhaø caàn tìm Output: found = True, tìm thaáy nhaø. Giaù trò haøm traû veà laø vò trí index cuûa nhaø vöøa tìm ñöôïc. found = False, khoâng tìm thaáy nhaø. Giaù trò traû veà laø vò trí index coù teân nhaø gaàn gioáng nhaát vôùi teân nhaø caàn tìm. Laáy thoâng tin cuûa moät nhaø Moãi khi ngöôøi duøng nhaán chuoät vaøo moät nhaø trong danh saùch nhaø, chöông trình seõ sinh ra moät thread teân THomeGetDataThread ñeå laáy moïi thoâng tin veà nhaø. procedure THomeGetDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; Haøm DoThread naøy chuû yeáu seõ goïi haøm HomeGet ñöôïc moâ taû nhö sau: function HomeGet(index : longint) : THomeInfo; var IndexData : longint; begin if (index homeCount) then exit; Seek(indexfile, index); Read(indexfile, IndexData); Seek(dataFile, IndexData); Read(dataFile, result); end; Ñöa vaøo index laø vò trí caàn laáy thoâng tin nhaø. Haøm naøy traû veà keát quaû kieåu ThomeInfo laø thoâng tin cuûa toaøn boä veà nhaø. Theâm thoâng tin moät nhaø môùi Hình 3.3.3 Khi baïn nhaán vaøo nuùt theâm nhaø môùi, moät khung trao ñoåi nhö treân seõ hieän ra ñeå baïn nhaäp thoâng tin veà nhaø môùi vaøo. Khi ñaõ ñieàn ñuû thoâng tin veà nhaø xong, nuùt OK seõ saùng leân ñeå cho pheùp baïn hoaøn thaønh coâng vieäc theâm nhaø môùi. Khi nuùt OK ñöôïc nhaán, moät thread teân TInsertDataThread ñöôïc sinh ra. procedure TInsertDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread chuû yeáu goïi haøm HomeInsert vaø ServerUpdateVLB ñöôïc moâ taû nhö sau: function HomeInsert(home : THomeInfo; var Index : longint) : boolean; Haøm naøy theâm moät nhaø môùi vaøo danh saùch nhaø. Input HomeInfo : Thoâng tin nhaø caàn theâm. Output index = -1 neáu khoâng thaønh coâng index > = 0 laø vò trí cuûa nhaø môùi theâm trong danh saùch nhaø. Ñaàu tieân ta ñöa döõ lieäu homeInfo vaøo cuoái datafile, sau ñoù ta tieán haønh caäp nhaät file index nhö sau: function HomeInsert (homeInfo : THomeInfo) : integer; begin IndexData := filesize(dataFile); Append HomeInfo vaøo cuoái DataFile; Tìm index cho nhaø môùi theâm vaøo Insert giaù trò IndexData vaøo indexfile taïi vò trí index end; Neáu vieäc theâm nhaø thaønh coâng, chöông trình seõ göûi moät thoâng ñieäp ñeán moïi client ñeå caäp nhaät danh saùch nhaø vöøa môùi bò thay ñoåi baèng caùch goïi haøm ServerUpdateVLB ñöôïc moâ taû nhö döôùi ñaây: procedure TChatForm.ServerUpdateVLB; var i : integer; begin VLB.NumItems := HomeData.HomeGetCount; for i := 0 to ServerSocket.Socket.ActiveConnections - 1 do SendMessageToClient(ServerSocket.Socket.Connections[i], idSetVLBNumItems, VLB.NumItems, fHome); end; Xoùa thoâng tin moät nhaø Khi baïn choïn moät nhaø trong danh saùch nhaø roài nhaán nuùt xoùa nhaø, moät khung trao ñoåi Confirm hieän ra töông töï nhö sau: Nhaán nuùt OK ñeå quyeát ñònh xoùa caên nhaø taïi vò trí hieän haønh trong danh saùch nhaø. Khi aáy chöông trình seõ taïo ra moät thread teân TDeleteThread: procedure TDeleteThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread chuû yeáu goïi haøm HomeDelete(index) vaø ServerUpdateVLB. function HomeDelete (index : longint) : boolean; begin Delete 1 record taïi vò trí index cuûa indexfile end; Neáu vieäc xoùa nhaø thaønh coâng, chöông trình seõ göûi moät thoâng ñieäp ñeán moïi client ñeå caäp nhaät danh saùch nhaø vöøa môùi bò thay ñoåi baèng caùch goïi haøm ServerUpdateVLB nhö treân. Caäp nhaät thoâng tin moät nhaø Hình 3.3.5. Khi nhaán nuùt Thay Ñoåi Thoâng Tin Nhaø, moät khung trao ñoåi töông töï ñeå theâm nhaø môùi hieän ra. Caùc oâ nhaäp ñaõ ñöôïc ñieàn saün thoâng tin. Baïn coù theå söûa ñoåi moät vaøi choã sai soùt roài nhaán nuùt OK ñeå hoaøn thaønh vieäc söûa ñoåi thoâng tin. Khi nhaán nuùt OK, moät thread teân TModifyDataThread seõ ñöôïc sinh ra. procedure TModifyDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread chuû yeáu goïi haøm HomeModify ñöôïc moâ taû döôùi ñaây: Haøm HomeModify caäp nhaät thoâng tin nhaø trong bieán Home taïi vò trí index. Haøm traû veà giaù trò True neáu thaønh coâng, ngöôïc laïi cho giaù trò False. Thöïc chaát cuûa haøm naøy laø laøm 2 thao taùc: xoùa thoâng tin nhaø taïi vò trí index roài theâm nhaø môùi vaøo danh saùch vôùi thoâng tin naèm trong bieán Home. Ñöa vaøo : Home : Thoâng tin môùi veà caên nhaø Index : Vò trí trong danh saùch nhaø caàn söûa ñoåi thoâng tin Cho ra: Index : Vò trí môùi trong danh saùch nhaø Result = True neáu thaønh coâng, False neáu thaát baïi. function HomeModify(Home : ThomeInfo; var index : integer) : boolean; begin result := HomeDelete(index); if result then result := HomeInsert(home, index); end; Thoáng keâ soá nhaø ñaõ cho thueâ Ngöôøi quaûn lyù coù theå thoáng keâ caùc nhaø ñaõ cho thueâ. Nhaán chuoät vaøo nuùt Thoáng Keâ Nhaø Cho Thueâ, moät khung trao ñoåi Thoáng Keâ Nhaø Cho Thueâ hieän ra nhö döôùi ñaây: Trong khung trao ñoåi naøy chöùa danh saùch caùc nhaø ñaõ cho thueâ. Baïn coù theå click chuoät vaøo moät nhaø trong danh saùch naøy ñeå xem thoâng tin chi tieát veà noù. Trong phaàn chi tieát naøy cuõng chöùa thoâng tin veà thôøi gian baét ñaàu cho thueâ vaø ngaøy thueâ cuoái cuøng, döïa vaøo ñaây, ngöôøi quaûn lyù coù theå ñöa caùc nhaø ñaõ heát haïn cho thueâ chôû veà danh saùch nhaø coù theå cho thueâ. Ñeám soá nhaø ñaõ cho thueâ Baïn coù theå ñeám coù bao nhieâu nhaø ñaõ cho thueâ baèng caùch nhaán nuùt Ñeám Nhaø Ñaõ Thueâ, moät khung trao ñoåi nhö sau hieän ra nhö sau ñaây cho baïn thoâng tin coù taát caû bao nhieâu nhaø ñaõ cho thueâ. Ñeå ñeám soá nhaø ñaõ cho thueâ, chöông trình sinh ra moät thread teân HomeRentCountThread procedure THomeRentCountThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread nhö sau : procedure THomeRentCountThread.DoThread; begin RepThueForm.fHom._.eRentCount := ChatForm.HomeData.HomeGetCountRent; end; Ñöa moät nhaø ñaõ heát haïn cho thueâ veà danh saùch caùc nhaø coù theå cho thueâ Ñeå ñöa moät nhaø ñaõ heát haïn cho thueâ veà danh saùch caùc nhaø coù theå cho thueâ, baïn haõy nhaán nuùt Heát Thueâ Nhaø, moät khung trao ñoåi Confirm hieän ra nhö döôùi ñaây: Nhaán nuùt Nhaän ñeå quyeát ñònh vieäc thoâi cho thueâ nhaø. Giaûi thuaät cho vieäc ñöa moät nhaø heát haïn thueâ nhaø veà danh saùch nhaø coù theå cho thueâ Sinh ra moät thread teân TUnRentThread: procedure TUnRentThread.Execute; begin EnterCriticalSection(CritSect); // Vaøo vuøng tranh chaáp Synchronize(DoThread); LeaveCriticalSection(CritSect); // Ra khoûi vuøng tranh chaáp end; DoThread thöïc hieän nhö sau: procedure TUnRentThread.DoThread; var i, count : integer; fHome : THomeInfo; begin if ChatForm.HomeData.HomeUnRent(FIndex) then // Neáu goïi haøm HomeUnRent thaønh coâng begin Count := ChatForm.homeData.HomeGetCount; // Count laø toång soá nhaø coù theå cho thueâ hay baùn for i := 0 to ChatForm.ServerSocket.Socket.ActiveConnections - 1 do ChatForm.SendMessageToClient(ChatForm.ServerSocket.Socket.Connections[i], idSetVLBNumItems, Count, fHome); // Göûi thoâng ñieäp ñeán toaøn boä client yeâu caàu caäp nhaät laïi danh saùch caùc nhaø cho thueâ hoaëc baùn end; end; Noäi dung cuûa haøm HomeUnRent: function THomeData.HomeUnRent(delindex : longint) : boolean; (* Ñöa vaøo delindex : vò trí caàn xoùa khoûi danh saùch nhaø ñaõ cho thueâ Cho ra Result = true neáu thaønh coâng Result = false neáu thaát baïi *) var buf : pchar; fHome : THomeInfo; index, count : longint; trent: TIndexFile; begin seek(rentfile, delindex); read(rentfile, index); //Laáy index laø vò trí cuûa record chöùa thoâng tin veà nhaø trong datafile töø rentfile. seek(datafile, index); read(datafile, fHome); // Laáy thoâng tin nhaø vaøo bieán fHome HomeInsert(fHome, index); // Theâm thoâng tin nhaø naøy vaøo danh saùch nhaø coù theå cho thueâ hoaëc baùn // Caùc leänh sau ñaây ñeå caét 4 byte ôû vò trí delindex khoûi rentfile (sau khi laøm xong rentfile seõ giaûm ñi 4 bytes. assignfile(trent, pathname + '1z2y3x4w.qgb'); rewrite(trent); // Taïo ra moät file trent taïm thôøi count := delindex; if count > 0 then // Cheùp moät block töø ñaàu file rentfile ñeán delindex – 1 vaøo trent begin getmem(buf, count*idxtypeSize); seek(rentfile, 0); blockread(rentfile, buf^, count); blockwrite(trent, buf^, count); freemem(buf, count*idxtypesize); end; count := filesize(rentfile) - count - 1; if count > 0 then // Cheùp moät khoái töø vò trí delindex + 1 trong rentfile vaøo trent begin getmem(buf, count*idxtypesize); seek(rentfile, delindex + 1); blockread(rentfile, buf^, count); blockwrite(trent, buf^, count); freemem(buf, count*idxTypesize); end; result := IOResult = 0; if result then // Neáu khoâng xaûy ra loãi, ñoùng 2 file rentfile vaø trent; xoùa rentfile; ñoåi teân trent thaønh rentfile roài môû laïi rentfile begin CloseFile(trent); CloseFile(rentfile); Erase(rentfile); Rename(trent, rentfilename); AssignFile(rentfile, rentfilename); Reset(rentfile); end; result := IOresult = 0; end; Thoáng keâ soá nhaø ñaõ baùn Ngöôøi quaûn lyù coù theå thoáng keâ caùc nhaø ñaõ baùn. Nhaán chuoät vaøo nuùt Thoáng Keâ Nhaø Ñaõ Baùn, moät khung trao ñoåi Thoáng Keâ Nhaø Ñaõ Baùn hieän ra nhö döôùi ñaây: Trong khung trao ñoåi naøy chöùa danh saùch caùc nhaø ñaõ baùn ñiâ. Baïn coù theå click chuoät vaøo moät nhaø trong danh saùch naøy ñeå xem thoâng tin chi tieát veà noù. Ñeám soá nhaø ñaõ baùn Baïn coù theå ñeám coù bao nhieâu nhaø ñaõ baùn baèng caùch nhaán nuùt Ñeám Nhaø Ñaõ Baùn, moät khung trao ñoåi nhö sau hieän ra nhö sau ñaây cho baïn thoâng tin coù taát caû bao nhieâu nhaø ñaõ baùn. Ñeå ñeám soá nhaø ñaõ baùn, chöông trình sinh ra moät thread teân HomeSellCountThread procedure THomeSentCountThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread nhö sau : procedure THomeSellCountThread.DoThread; begin RepThueForm.fHomeSellCount := ChatForm.HomeData.HomeGetCountSell; end; Caùc chöùc naêng cho ngöôøi caäp nhaät thoâng tin nhaø Döôùi ñaây laø khung trao ñoåi chính daønh cho ngöôøi caäp nhaät döõ lieäu nhaø: Tìm kieám moät nhaø Khi ngöôøi caäp nhaät thoâng tin nhaø goõ vaøo oâ soaïn thaûo tìm kieám, chöông trình seõ göûi moät thoâng ñieäp tìm kieám ñeán maùy server keøm theo noäi dung teân nhaø hoï ñaõ ñaùnh vaøo. Maùy server seõ tieán haønh vieäc tìm kieám naøy (Taïo ra moät thread teân THomeSearchTextThread) vaø traû veà cho client index cuûa teân nhaø gaàn gioáng nhaát tìm thaáy trong danh saùch nhaø. Laáy thoâng tin cuûa moät nhaø Khi ngöôøi caäp nhaät töø ñieån nhaán chuoät vaøo moät nhaø trong danh saùch nhaø, chöông trình seõ göûi moät thoâng ñieäp laáy thoâng tin nhaø ñeán maùy server, keøm theo vò trí cuûa nhaø naøy trong danh saùch nhaø. Maùy server seõ tieán haønh vieäc laáy thoâng tin nhaø (Taïo ra moät thread teân THomeGetDataThread) vaø göûi keát quaû veà cho client. Khi ñaõ laáy ñöôïc döõ lieäu treân server, chöông trình client seõ hieån thò thoâng tin nhaø maø baïn vöøa click chuoät leân maøn hình. Caäp nhaät thoâng tin moät nhaø Khi ngöôøi caäp nhaät töø ñieån nhaán nuùt Caäp Nhaät Thoâng Tin Nhaø, moät khung trao ñoåi töông töï nhö hình 3.3.5. hieän ra, nhöõng thoâng tin cuõ ñaõ ñöôïc ñieàn saün roài, baïn coù theå söûa moät vaøi choã sai soùt sau ñoù nhaán nuùt OK. Ngay luùc ñoù chöông trình seõ göûi moät thoâng ñieäp caäp nhaät thoâng tin nhaø ñeán chöông trình treân maùy server, keøm theo vò trí vaø thoâng tin môùi cuûa nhaø vöøa môùi söûa ñoåi naøy. Maùy server seõ tieán haønh vieäc caäp nhaät thoâng tin nhaø (Taïo ra moät thread teân TModifyDataThread) cho client. Theâm thoâng tin moät nhaø môùi Nhaán vaøo nuùt theâm nhaø môùi, moät khung trao ñoåi nhö hình 3.3. seõ hieän ra ñeå baïn nhaäp thoâng tin veà nhaø môùi vaøo. Sau khi ñaõ ñieàn ñuû thoâng tin veà nhaø xong, nuùt OK seõ saùng leân ñeå cho pheùp baïn hoaøn thaønh coâng vieäc theâm nhaø môùi. Khi nuùt OK ñöôïc nhaán, chöông trình seõ göûi moät thoâng ñieäp yeâu caàu theâm nhaø môùi cho server, keøm theo thoâng tin cho nhaø baïn vöøa nhaäp vaøo. Chöông trình chaïy treân maùy server khi nhaän ñöôïc thoâng ñieäp naøy seõ sinh ra moät thread teân TInsertDataThread ñeå thöïc hieän vieäc theâm nhaø môùi. Neáu vieäc theâm nhaø thaønh coâng, moät thoâng ñieäp yeâu caàu caäp nhaät danh saùch nhaø seõ ñöôïc göûi ñeán cho toaøn boä client. Xoùa thoâng tin moät nhaø Choïn moät nhaø trong danh saùch nhaø caàn xoùa roài nhaán nuùt xoùa nhaø, moät khung trao ñoåi Confirm hieän ra nhö sau: Baïn nhaán nuùt Nhaän ñeå quyeát ñònh xoùa, khi aáy chöông trình seõ göûi moät thoâng ñieäp yeâu caàu xoùa nhaø ñeán chöông trình server keøm theo vò trí trong danh saùch nhaø. Chöông trình server khi nhaän ñöôïc thoâng baùo naøy seõ sinh ra moät thread teân TDeteleThread ñeå thöïc hieän vieäc xoùa nhaø. Neáu coâng vieäc xoùa nhaø thöïc hieän thaønh coâng, chöông trình server seõ göûi moät thoâng ñieäp yeâu caàu caäp nhaät danh saùch nhaø ñeán toaøn boä caùc client. Caùc chöùc naêng cho moät khaùch haøng Döôùi ñaây laø khung trao ñoåi chính daønh cho ngöôøi khaùch haøng: Laáy thoâng tin veà moät nhaø Khi ngöôøi khaùch haøng nhaán chuoät vaøo moät nhaø trong danh saùch nhaø, chöông trình seõ göûi moät thoâng ñieäp laáy thoâng tin nhaø ñeán maùy server, keøm theo vò trí cuûa nhaø naøy trong danh saùch nhaø. Maùy server seõ tieán haønh vieäc laáy thoâng tin nhaø (Taïo ra moät thread teân THomeGetDataThread) vaø göûi keát quaû veà cho client. Tìm kieám moät nhaø Khi ngöôøi khaùch haøng goõ vaøo oâ soaïn thaûo tìm kieám, chöông trình seõ göûi moät thoâng ñieäp tìm kieám ñeán maùy server keøm theo noäi dung teân nhaø hoï ñaõ ñaùnh vaøo. Maùy server seõ tieán haønh vieäc tìm kieám naøy (Taïo ra moät thread teân THomeSearchTextThread) vaø traû veà cho client index cuûa teân nhaø gaàn gioáng nhaát tìm thaáy trong danh saùch nhaø. Tìm kieám theo ñieàu kieän Chöông trình coøn coù khaû naêng cho pheùp khaùch haøng chæ lieät keä danh saùch caùc nhaø thoûa moät soá ñieàu kieän naøo ñoù. Chaúng haïn chæ lieät keâ caùc nhaø coù dieän tích lôùn nhaát vaø nhoû nhaát laø bao nhieâu; lieät keâ danh saùch caùc nhaø chæ ôû ngoaïi thaønh; lieät keâ danh saùch caùc nhaø chæ ôû noäi thaønh; lieät keâ danh saùch caùc nhaø coù giaù tieàn nhoû nhaát vaø lôùn nhaát laø bao nhieâu; lieät keâ danh saùch caùc nhaø cho thueâ; lieät keâ danh saùch caùc nhaø baùn. Ngöôøi khaùch haøng cuõng coù theå keát hôïp caùc löïa choïn laïi ñeå tìm cho chính xaùc. Dó nhieân khi keát hôïp nhieàu ñieàu kieän laïi, soá nhaø lieät keâ ra seõ ít ñi. Giaûi thuaät trong chöông trình: Khi khaùch haøng nhaán nuùt Tìm kieám theo ñieàu kieän, moät khung trao ñoåi Tìm kieám theo ñieàu kieän hieän ra nhö döôùi ñaây: Hình 3.53 Sau khi ñaõ nhaäp caùc thoâng tin caàn thieát cho vieäc tìm kieám, (ví duï neáu muoán chæ lieät keâ caùc nhaø cho thueâ, haõy choïn oâ kieåm nhaø cho thueâ,…) nhaán nuùt tìm kieám. Ngay luùc ñoù chöông trình client cuûa khaùch haøng seõ göûi moät thoâng ñieäp tìm kieám ñeán chöông trình server keøm theo noäi dung tìm kieám cuûa khaùch haøng. Khi chöông trình server nhaän ñöôïc thoâng ñieäp naøy, noù seõ sinh ra moät thread teân TFindThread. procedure TFindThread.DoThread; var x : xxType; begin FFilterCount := ChatForm.HomeData.HomeGetCount; // FfilterCount laø soá nhaø toái ña ñöôïc tìm thaáy. Getmem(FFilter, FFilterCount * sizeof(longint)); // Caáp phaùt nhôù cho Ffilter laø con troû chæ tôùi maûng kieåu longint ChatForm.HomeData.HomeFind(FFind.ThueBan, FFind.NgoaiNoiThanh, FFind.TriGiaMin, FFind.TriGiaMax, FFind.DienTichMin, FFind.DienTichMax, FFilter, FFilterCount); // Goïi haøm tìm kieám, keát quaû traû veà laø Ffilter, con troû maûng chöùa danh saùch index caùc nhaø tìm thaáy thoûa ñieàu kieän ñöa vaøo. FfilterCount laø soá nhaø thöïc söï ñaõ tìm thaáy FillChar(x, sizeof(x), 0); x.index := FFilterCount; StrCopy(x.mess, idFindResult); move(FFilter^, x.Home, FFilterCount * sizeof(longint)); // Ñöa giaù trò cuûa Ffilter vaø FilterCount vaøo bieán x. ChatForm.ServerSocket.Socket.Connections[FClient].SendBuf(x, sz); // Göûi moät thoâng ñieäp keøm theo keát quaû tìm kieám naèm trong bieán x cho Fclient ñoøi hoûi tìm kieám. Freemem(FFilter); // Giaûi phoùng nhôù cho FFilter end; TFindThread goïi haøm HomeFind ñöôïc moâ taû sau ñaây: function HomeFind (ThueBan, ViTri : Integer; GiaMin, GiaMax, SMin, SMax : real; var ListSelect : PArrInt; var FilterCount : longint) : boolean; Ñöa vaøo ThueBan = -1 : Boû qua löïa choïn naøy ThueBan = 0 : Choïn nhaø cho thueâ ThueBan = 1 : Choïn nhaø baùn Vòtrí = -1 : Boû qua löïa choïn naøy Vòtrí = 0 : Choïn nhaø ôû ngoaïi thaønh Vòtrí = 1 : Choïn nhaø ôû noäi thaønh GiaùMin < 0 : Boû qua löïa choïn naøy. GiaùMin >= 0 : GiaMin ñöôïc tính theo tieàn Vieät Nam. Neáu ThueBan = 0, GiaMin laø giaù tieàn thueâ haøng thaùng nhoû nhaát. Ngöôïc laïi, neáu ThueBan = 1, GiaMin laø giaù trò nhoû nhaát cuûa caên nhaø. GiaùMax < 0 : Boû qua löïa choïn naøy GiaùMax >= 0 : GiaMax ñöôïc tính theo tieàn Vieät Nam. Neáu ThueBan = 0, GiaMax laø giaù tieàn thueâ haøng thaùng lôùn nhaát. Ngöôïc laïi, neáu ThueBan = 1, GiaMax laø giaù trò lôùn nhaát cuûa caên nhaø. Smin < 0 : Boû qua löïa choïn naøy. Smin >= 0 : Dieän tích toái thieåu cuûa caên nhaø ñöôïc tính theo m vuoâng. Smax < 0 : Boû qua löïa choïn naøy. Smax >= 0 : Dieän tích toái ña cuûa caên nhaø ñöôïc tính theo m vuoâng. FilterCount soá nhaø trong danh saùch nhaø. Keát quaû : ListSelect : Con troû chæ tôùi danh saùch chöùa index cuûa caùc nhaø tìm thaáy. FilterCount : Soá löôïng nhaø thoûa maõn ñieàu kieän ñöa vaøo. function THomeData.HomeFind(ThueBan, ViTri : Integer; GiaMin, GiaMax, SMin, SMax : real; var ListSelect : PArrInt; var FilterCount : longint) : boolean; var Index : longint; Home : THomeInfo; Count : longint; begin Result := true; Count := FilterCount; // Count laø toång soá nhaø coù theå cho thueâ hoaëc baùn FilterCount := 0; // Khôûi taïo soá nhaø thoûa ñieàu kieän ñöa vaøo laø 0 for Index := 0 to Count - 1 do begin Home := HomeGet(Index); case ThueBan of 1 : if not Home.Nhaban then Continue; // Neáu khoâng phaûi nhaø baùn thì xeùt nhaø keá tieáp 0 : if not Home.NhaChoThue then Continue; // Neáu khoâng phaûi nhaø cho thueâ thì xeùt nhaø keá tieáp end; if ViTri >= 0 then // Neáu coù xeùt ñieàu kieän nhaø ôû vò trí noäi hay ngoaïi thaønh if Home.NhaNgoaiThanh (ViTri = 0) then Continue; // Neáu khoâng phuø hôïp vò trí nhaø thì xeùt ñeán nhaø keá tieáp if GiaMin >= 0 then // Neáu coù ñieàu kieän tìm nhaø vôùi giaù baùn hay thueâ nhaø beù nhaát if ThueBan = 0 then // Neáu tìm nhaø cho thueâ if Home.GiaMoiThang < GiaMin then Continue // Neáu Giamoithang < GiaùMin thì xeùt nhaø keá tieáp else else // Neáu tìm nhaø baùn if (ThueBan = 1) and (Home.TriGia) < GiaMin then Continue; // Neáu TriGia < GiaùMin thì xeùt nhaø keá tieáp if GiaMax >= 0 then // Neáu coù ñieàu kieän tìm nhaø vôùi giaù baùn hay thueâ nhaø lôùn nhaát if ThueBan = 0 then // Neáu tìm nhaø cho thueâ if Home.GiaMoiThang > GiaMax then Continue // Neáu Giamoithang > GiaùMax thì xeùt nhaø keá tieáp else else // Neáu tìm nhaø baùn if (ThueBan = 1) and (Home.TriGia > GiaMax) then Continue; // Neáu TriGia < GiaùMin thì xeùt nhaø keá tieáp if SMin >= 0 then // Neáu coù ñieàu kieän tìm nhaø vôùi dieän tích nhaø beù nhaát if Home.DienTich < SMin then Continue; // Neáu Dieän tích nhaø nhoû hôn Smin thì xeùt ñeán nhaø keá tieáp if SMax >= 0 then // Neáu coù ñieàu kieän tìm nhaø vôùi dieän tích nhaø lôùn nhaát if Home.DienTich > SMax then Continue; // Neáu Dieän tích nhaø lôùn hôn SMax thì xeùt ñeán nhaø keá tieáp // Taát caû ñieàu kieän ñöa vaøo ñeàu thoûa thì löu Index vaøo ListSelect roài taêng soá nhaø // tìm ñöôïc leân 1 ListSelect[FilterCount] := Index; Inc(FilterCount); if FilterCount >= MaxFilterCount then Break; // Neáu soá nhaø thoûa ñieàu kieän cho vaøo lôùn hôn MaxFilterCount thì khoâng caàn tìm nöõa end; end; Khi baïn nhaán chuoät vaøo moät nhaø baát kyø trong danh saùch nhaø tìm ra thì laäp töùc trong danh saùch caùc nhaø cho thueâ hoaëc baùn cuûa khung trao ñoåi chính cuûa chöông trình cuõng nhaûy tôùi nhaø naøy. Ñeán luùc naøy, baïn coù theå ñaêng kyù mua hay thueâ caên nhaø maø baïn ñaõ tìm. Giaûi thuaät laäp trình ñeå nhaûy tôùi moät nhaø trong danh saùch nhaø töø khung trao ñoåi tìm kieám: Göûi moät thoâng ñieäp WM_CHANGEINDEX töï ñònh nghóa nhö sau: SendMessage(ChatForm.Handle, WM_ChangeIndex, Filter[Index], 0); Trong khung trao ñoåi chính cuûa chöông trình seõ ñoùn thoâng ñieäp naøy: TChatForm = class(TShadowForm) … .., public procedure ChangeIndex(var msg : TMessage); message WM_ChangeIndex; end; procedure TChatForm.ChangeIndex(var msg : TMessage); var Index : integer; begin Index := msg.WParam; if index < 0 then exit; VLB.ItemIndex := index; // Thay ñoåi index trong danh saùch nhaø VLBClick(nil); // Hieån thò thoâng tin nhaø ra maøn hình end; Ñaêng kyù thueâ nhaøø Khi khaùch haøng nhaán nuùt ñaêng kyù thueâ nhaø, chöông trình seõ kieåm tra xem caên nhaø ñoù coù phaûi laø ñeå cho thueâ khoâng (baèng caùch xem Home.NhaChoThue). * Neáu khoâng phaûi nhaø cho thueâ moät khung trao ñoåi nhaéc nhôû hieän ra nhö döôùi ñaây: * Neáu laø nhaø cho thueâ, moät khung trao ñoåi Thueâ Nhaø hieän ra sau ñaây: Baïn haõy nhaäp tham soá Töø Ngaøy, Ñeán Ngaøy sau ñoù nhaán nuùt Nhaän ñeå quyeát ñònh thueâ nhaø. Thao taùc trong chöông trình ñeå cho thueâ moät caên nhaø laøm nhö sau: Chöông trình client seõ göûi moät thoâng ñieäp ñeán server yeâu caàu thueâ nhaø keøm theo ngaøy thueâ vaø vò trí cuûa nhaø trong danh saùch nhaø. Khi nhaän ñöôïc thoâng ñieäp thueâ nhaø naøy, chöông trình server seõ taïo ra moät thread teân TthueNhaThread: procedure TThueNhaThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread chuû yeáu goïi haøm HomeRent nhö sau: if HomeData.HomeRent(index, NgayDau, NgayCuoi) then ServerUpdateVLB function THomeData.HomeRent(index : longint; NgayDau, NgayCuoi : TDateTime) : boolean; (* Ñöa vaøo : index : Vò trí nhaø caàn thueâ trong danh saùch nhaø NgayDau : Ngaøy baét ñaàu thueâ nhaø NgayCuoi: Ngaøy cuoái cuøng thueâ nhaø Ra : Result = True neáu thaønh coâng Result = False neáu thaát baïi *) var dataindex, count : longint; buf : pchar; ftidx : TIndexfile; fHome : THomeInfo; begin result := false; if index < 0 then exit; seek(indexfile, index); read(indexfile, dataindex); // dataindex laø vò trí cuûa thoâng tin nhaø trong datafile seek(datafile, dataindex); read(datafile, fhome); fhome.NgayDauThue := NgayDau; fHome.NgayCuoiThue := NgayCuoi; seek(datafile, dataindex); write(datafile, fhome); // Caäp nhaät ngaøy thueâ nhaø vaøo datafile seek(rentfile, filesize(rentfile)); write(rentfile, dataindex); // Ghi 4 byte cuûa dataindex vaøo cuoái rentfile // Caùc leänh sau ñaây ñeå xoùa 4 byte taïi vò trí index trong indexfile. Sau khi thöïc hieän, indexfile giaûm 4 byte assignfile(ftidx, pathname + '1z2y3x4w.qgb'); rewrite(ftidx); count := index; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, 0); blockread(IndexFile, buf^, count); blockwrite(ftIdx, buf^, count); freemem(buf, count*idxtypeSize); end; count := filesize(IndexFile)- count - 1; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, index + 1); blockread(IndexFile, buf^, count); blockwrite(ftidx, buf^, count); freemem(buf, count*idxtypeSize); end; result := IOResult = 0; if result then begin CloseFile(ftIdx); CloseFile(IndexFile); Erase(IndexFile); Rename(ftIdx, indexfilename); AssignFile(IndexFile, indexfilename); Reset(IndexFile); end; end; Ñaêng kyù mua nhaø Khi khaùch haøng nhaán nuùt ñaêng kyù mua nhaø, chöông trình seõ kieåm tra xem caên nhaø ñoù coù phaûi laø ñeå baùn khoâng (baèng caùch xem Home.NhaBan). * Neáu khoâng phaûi nhaø baùn moät khung trao ñoåi nhaéc nhôû hieän ra nhö döôùi ñaây: * Neáu laø nhaø baùn, moät khung trao ñoåi sau ñaây hieän ra: Nhaán nuùt Nhaän ñeå quyeát ñònh mua caên nhaø ñaõ choïn. Thao taùc trong chöông trình ñeå cho mua moät caên nhaø laøm nhö sau: Chöông trình client seõ göûi moät thoâng ñieäp ñeán server yeâu caàu mua nhaø keøm theo vò trí cuûa nhaø trong danh saùch nhaø. Khi nhaän ñöôïc thoâng ñieäp thueâ nhaø naøy, chöông trình server seõ taïo ra moät thread teân TMuaNhaThread: procedure TMuaNhaThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; DoThread trong mua nhaø chuû yeáu goïi leänh sau: if HomeData.HomeSell(index) then ServerUpdateVLB YÙ nghóa cuûa haøm HomSell nhö sau: function THomeData.HomeSell(index : longint) : boolean; var count, dataIndex : longint; buf : pchar; ftidx : TIndexfile; begin result := false; if index < 0 then exit; seek(indexfile, index); read(indexfile, dataindex); // dataindex laø vò trí cuûa thoâng tin nhaø trong datafile seek(sellfile, filesize(sellfile)); write(sellfile, dataindex); // Ghi 4 byte cuûa dataindex vaøo cuoái sellfile // Caùc leänh sau ñaây ñeå xoùa 4 byte taïi vò trí index trong indexfile. Sau khi thöïc hieän, indexfile giaûm 4 byte assignfile(ftidx, pathname + '1z2y3x4w.qgb'); rewrite(ftidx); count := index; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, 0); blockread(IndexFile, buf^, count); blockwrite(ftIdx, buf^, count); freemem(buf, count*idxtypeSize); end; count := filesize(IndexFile)- count - 1; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, index + 1); blockread(IndexFile, buf^, count); blockwrite(ftidx, buf^, count); freemem(buf, count*idxtypeSize); end; result := IOResult = 0; if result then begin CloseFile(ftIdx); CloseFile(IndexFile); Erase(IndexFile); Rename(ftIdx, indexfilename); AssignFile(IndexFile, indexfilename); Reset(IndexFile); end; end; Dó nhieân thoâng tin veà caên nhaø vöøa baùn seõ khoâng bò maát ñi. Ngöôøi quaûn lyù vaãn coù theå xem thoâng tin veà caùc nhaø ñaõ baùn. Maõ chöông trình kinh doanh nhaø ñaát treân maïng client/server Nha.dpr Nha.dpr laø chöông trình chính. (* nha.dpr Written by Le Tuan *) program nha; uses Graphics, Controls, Forms, nhaf in 'nhaf.pas' {ChatForm}, conectdlg in 'conectdlg.pas' {ConnectDlg}, myThread in 'myThread.pas', homeInfo in 'homeInfo.pas' {HomeInfoForm}, hometools in 'hometools.pas', findf in 'Findf.pas' {FindForm}, mytdrtf in 'mytdrtf.pas', repthuef in 'repthuef.pas' {RepThueForm}, inputthuef in 'inputthuef.pas' {InputThue}, informf in 'informf.pas' {InfoForm}; {$R *.RES} begin ConnectDlg := TConnectDlg.Create(Application); with ConnectDlg do begin if ShowModal = mrOK then begin ChatForm := TChatForm.Create(application); ChatForm.ShowModal; ChatForm.Release; end; Release; end; end. Nhaf.pas Nhaf.pas chöùa khung trao ñoåi chính cuûa chöông trình. Khung trao ñoåi naøy duøng chung cho caû 3 ñoái töôïng ngöôøi söû duïng, tuy nhieân cuõng coù moät soá khaùc bieät nhoû. (* nhaf.pas Written by Le Tuan *) unit nhaf; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, Buttons, ScktComp, ExtCtrls, ComCtrls, VLB, homeInfo, HomeTools, MyThread, Findf, Tranbtn, ShadowForm, mytdRTF, myDialog, inputthuef, QFButton, InformF; const WM_ChangeIndex = WM_USER + 5000; type TChatForm = class(TShadowForm) Image1: TImage; VLB: TVLB; TextSearch: TEdit; Label1: TLabel; Bevel1: TBevel; RichEdit1: TRichEdit; Bevel2: TBevel; Bevel3: TBevel; AdminLTBtnAdd: TLTBtn; AdminLTBtnModify: TLTBtn; AdminLTBtnDel: TLTBtn; DicLTBtnModify: TLTBtn; DicLTBtnDel: TLTBtn; DicLTBtnAdd: TLTBtn; Bevel4: TBevel; ClientSocket: TClientSocket; ServerSocket: TServerSocket; CusLTBtnFind: TLTBtn; CusLTBtnThue: TLTBtn; CusLTBtnBan: TLTBtn; AdminLTBtnRepThue: TLTBtn; Image2: TImage; AdminLTBtnRepBan: TLTBtn; Image3: TImage; QFButton1: TQFButton; Image4: TImage; LabelName: TLabel; procedure FormPaint(Sender: TObject); procedure FormCreate(Sender: TObject); procedure VLBGetItem(Sender: TObject; Index: Integer; var ItemString: String); procedure VLBClick(Sender: TObject); procedure ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); procedure CusLTBtnFindClick(Sender: TObject); procedure CusLTBtnThueClick(Sender: TObject); procedure CusLTBtnBanClick(Sender: TObject); procedure DicLTBtnModifyClick(Sender: TObject); procedure DicLTBtnDelClick(Sender: TObject); procedure DicLTBtnAddClick(Sender: TObject); procedure AdminLTBtnAddClick(Sender: TObject); procedure AdminLTBtnDelClick(Sender: TObject); procedure AdminLTBtnModifyClick(Sender: TObject); procedure TextSearchChange(Sender: TObject); procedure TextSearchKeyPress(Sender: TObject; var Key: Char); procedure AdminLTBtnRepThueClick(Sender: TObject); procedure AdminLTBtnRepBanClick(Sender: TObject); procedure QFButton1Click(Sender: TObject); procedure FormActivate(Sender: TObject); private { Private declarations } procedure wmNcHitTest(var Msg : TwmNcHitTest); message wm_NcHitTest; function TestTLTBtn(p : TPoint) : boolean; procedure DrawForm(Level : integer); private function FindClient(ClientSocket : TCustomWinSocket) : integer; procedure ShowData; procedure ConnectAdmin; procedure ConnectModifier; procedure ConnectCustomer; function SetHomeInfo(hasDefault : boolean) : boolean; procedure ServerUpdateVLB; procedure FileListenItemClick(Sender: TObject); public homeData : THomeData; fHome, ffhome : THomeInfo; fIndex : longint; procedure InsertData(Home : THomeInfo); procedure ModifyData(index : longint; Home : THomeInfo); procedure MuaNha(Index : Longint); procedure ThueNha(Index : Longint; NgayDau, NgayCuoi : TDateTime); procedure DeleteNha(Index : Longint); procedure SendMessageToServer(Socket : TCustomWinSocket; mess : pchar; index : longint; home : THomeInfo); procedure SendMessageToClient(Socket : TCustomWinSocket; mess : pchar; index : longint; home : THomeInfo); procedure ChangeIndex(var msg : TMessage); message WM_ChangeIndex; public { Public declarations } procedure DrawShadowBox(fCanvas : TCanvas; R: TRect); procedure DrawShadow(fCanvas : TCanvas; R: TRect); procedure PaintBack(fCanvas : TCanvas; B : TBitmap); end; type TMyHintWindow = class(THintWindow) constructor Create(AOwner : TComponent); override; end; type xxType = packed record mess : array[0..19] of char; index : longint; Home : THomeInfo; end; const sz = sizeof(xxType); idGetData : pchar = '$GetData$'; idSetData : pchar = '$SetData$'; idGetItem : pchar = '$GetItem$'; idSetItem : pchar = '$SetItem$'; idGetVLBNumItems : pchar = '$GetVLBNumItems$'; idSetVLBNumItems : pchar = '$SetVLBNumItems$'; idSetPageControl : pchar = '$idSetPageControl$'; idInsertData : pchar = '$idInsertData$'; idModifyData : pchar = '$idModifyData$'; idDelete : pchar = '$idDelete$'; idMuaNha : pchar = '$idMuaNha$'; idThueNha : pchar = '$idThueNha$'; idTimNha : pchar = '$idTimNha$'; idFind : pchar = '$idfind$'; idFindResult : pchar = '$idFindResult$'; idPaintVLB : pchar = '$idPaintVLB$'; idSetItemFilter : pchar = '$idSetItemFilter$'; idGetItemFilter : pchar = '$idGetItemFilter$'; idSetIndex : pchar = '$idSetIndex$'; Received : Boolean = false; DataReceived : Boolean = false; ItemReceived : Boolean = false; ClientConnected : Boolean = false; ListenChecked : Boolean = False; IsServer : Boolean = false; VLBClicking : boolean = false; var ChatForm: TChatForm; Server: String; CritSect : TRTLCriticalSection; implementation uses conectdlg, repthuef; {$R *.DFM} function GetPath : string; var i : byte; begin result := ParamStr(0); i := length(result); while (i > 0) and (result[i] '\') do dec(i); result := copy(result, 1, i); end; procedure WaitForReceived; begin repeat Application.ProcessMessages; until Received; end; constructor TMyHintWindow.Create(Aowner:TComponent); begin inherited Create(Aowner); Canvas.Font.Name := 'Vietnam'; Canvas.Font.Size := 8; end; procedure TChatForm.ModifyData(index : longint; Home : THomeInfo); begin if HomeData.HomeModify(home, index) then ServerUpdateVLB else VMessageDlg('Lši thuˆ nh… "' + Home.TenNha + '"', mtInformation, [mbOk], 0); end; procedure TChatForm.InsertData; var Index : longint; begin HomeData.HomeInsert(Home, index); ServerUpdateVLB; end; procedure TChatForm.MuaNha(Index : Longint); begin if HomeData.HomeSell(index) then ServerUpdateVLB else VMessageDlg('Lši mua nh… "' + fHome.TenNha + '"', mtInformation, [mbOk], 0); end; procedure TChatForm.ThueNha(Index : Longint; NgayDau, NgayCuoi : TDateTime); begin if HomeData.HomeRent(index, NgayDau, NgayCuoi) then ServerUpdateVLB else VMessageDlg('Lši thuˆ nh… "' + fHome.TenNha + '"', mtInformation, [mbOk], 0); end; procedure TChatForm.DeleteNha(Index : Longint); begin if HomeData.HomeDelete(index) then ServerUpdateVLB else VMessageDlg('Lši delete nh… "' + fHome.TenNha + '"', mtInformation, [mbOk], 0); end; procedure TChatForm.PaintBack(fCanvas : TCanvas; B : TBitmap); var X, Y, W, H: LongInt; begin with B do begin W := Width; H := Height; end; Y := 0; while Y <= Height do begin X := 0; while X <= Width do begin fCanvas.Draw(X, Y, B); Inc(X, W); end; Inc(Y, H); end; end; procedure TChatForm.DrawShadowBox(fCanvas : TCanvas; R: TRect); begin with fCanvas do begin Brush.Style := bsSolid; FillRect(R); Pen.Width := 3; Pen.Style := psSolid; Pen.Color := 155548 or $02000000; MoveTo(R.Left + 6, R.Bottom + 1); LineTo(R.Right + 1, R.Bottom + 1); LineTo(R.Right + 1, R.Top + 6); end; end; procedure TChatForm.DrawShadow(fCanvas : TCanvas; R: TRect); begin with fCanvas do begin Brush.Style := bsSolid; Brush.Color := 15007741 or $02000000; Pen.Width := 3; Pen.Style := psSolid; Pen.Color := 11548; MoveTo(R.Left + 6, R.Bottom + 1); LineTo(R.Right + 1, R.Bottom + 1); LineTo(R.Right + 1, R.Top + 6); end; end; procedure TChatForm.FormPaint(Sender: TObject); begin PaintBack(Canvas, Image1.Picture.Bitmap); DrawShadow(Canvas, Bevel2.BoundsRect); DrawShadow(Canvas, Bevel3.BoundsRect); end; function TChatForm.TestTLTBtn(p : TPoint) : boolean; var i : integer; begin result := false; for i := 0 to ControlCount - 1 do begin if (Controls[i] is TLTBtn) and (PtInRect((Controls[i] as TLTBtn).BoundsRect, p)) then Exit; if (Controls[i] is TQFButton) and (PtInRect((Controls[i] as TQFButton).BoundsRect, p)) then Exit; end; result := true; end; procedure TChatForm.wmNcHitTest(var Msg : TwmNcHitTest); begin inherited; if TestTLTBtn(ScreenToClient(Point(Msg.Pos.X, Msg.Pos.Y))) then Msg.Result := HTCAPTION; end; procedure TChatForm.DrawForm; begin VLB.Height := 170; Bevel4.Top := 287; case Level of 0: begin CusLTBtnFind.Visible := true; CusLTBtnThue.Visible := true; CusLTBtnBan.Visible := true; ._.nt := index; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, 0); blockread(IndexFile, buf^, count); blockwrite(ftIdx, buf^, count); freemem(buf, count*idxtypeSize); end; count := filesize(IndexFile)- count - 1; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, index + 1); blockread(IndexFile, buf^, count); blockwrite(ftidx, buf^, count); freemem(buf, count*idxtypeSize); end; result := IOResult = 0; if result then begin CloseFile(ftIdx); CloseFile(IndexFile); Erase(IndexFile); Rename(ftIdx, indexfilename); AssignFile(IndexFile, indexfilename); Reset(IndexFile); end; end; function THomeData.HomeGetCountSell : longint; begin result := filesize(sellfile); end; function THomeData.HomeGetSell(index: longint): THomeInfo; begin seek(sellfile, index); read(sellfile, index); seek(datafile, index); read(datafile, result); end; function THomeData.HomeRent(index : longint; NgayDau, NgayCuoi : TDateTime) : boolean; var dataindex, count : longint; buf : pchar; ftidx : TIndexfile; fHome : THomeInfo; begin result := false; if index < 0 then exit; seek(indexfile, index); read(indexfile, dataindex); seek(datafile, dataindex); read(datafile, fhome); fhome.NgayDauThue := NgayDau; fHome.NgayCuoiThue := NgayCuoi; seek(datafile, dataindex); write(datafile, fhome); seek(rentfile, filesize(rentfile)); write(rentfile, dataindex); assignfile(ftidx, pathname + '1z2y3x4w.qgb'); rewrite(ftidx); count := index; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, 0); blockread(IndexFile, buf^, count); blockwrite(ftIdx, buf^, count); freemem(buf, count*idxtypeSize); end; count := filesize(IndexFile)- count - 1; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(IndexFile, index + 1); blockread(IndexFile, buf^, count); blockwrite(ftidx, buf^, count); freemem(buf, count*idxtypeSize); end; result := IOResult = 0; if result then begin CloseFile(ftIdx); CloseFile(IndexFile); Erase(IndexFile); Rename(ftIdx, indexfilename); AssignFile(IndexFile, indexfilename); Reset(IndexFile); end; end; function THomeData.HomeGetCountRent : longint; begin result := filesize(rentfile); end; function THomeData.HomeGetRent(index: longint): THomeInfo; begin seek(rentfile, index); read(rentfile, index); seek(datafile, index); read(datafile, result); end; function THomeData.HomeFind(ThueBan, ViTri : Integer; GiaMin, GiaMax, SMin, SMax : real; var ListSelect : PArrInt; var FilterCount : longint) : boolean; var Index : longint; Home : THomeInfo; Count : longint; begin Result := true; Count := FilterCount; FilterCount := 0; for Index := 0 to Count - 1 do begin Home := HomeGet(Index); case ThueBan of 1 : if not Home.Nhaban then Continue; 0 : if not Home.NhaChoThue then Continue; end; if ViTri >= 0 then if Home.NhaNgoaiThanh (ViTri = 0) then Continue; if GiaMin >= 0 then if ThueBan = 0 then if Home.GiaMoiThang < GiaMin then Continue else else if (ThueBan = 1) and (Home.TriGia < GiaMin) then Continue; if GiaMax >= 0 then if ThueBan = 0 then if Home.GiaMoiThang > GiaMax then Continue else else if (ThueBan = 1) and (Home.TriGia > GiaMax) then Continue; if SMin >= 0 then if Home.DienTich < SMin then Continue; if SMax >= 0 then if Home.DienTich > SMax then Continue; ListSelect[FilterCount] := Index; Inc(FilterCount); if FilterCount >= MaxFilterCount then Break; end; end; procedure RaVND(var x : real; o : integer); begin case o of 1 : x := x * _USD; //USD 2 : x := x * _CAY; //Cayvang end; end; function THomeData.HomeUnRent(delindex : longint) : boolean; var buf : pchar; fHome : THomeInfo; index, count : longint; trent: TIndexFile; begin seek(rentfile, delindex); read(rentfile, index); seek(datafile, index); read(datafile, fHome); HomeInsert(fHome, index); //remove recdeleted from rentfile assignfile(trent, pathname + '1z2y3x4w.qgb'); rewrite(trent); count := delindex; if count > 0 then begin getmem(buf, count*idxtypeSize); seek(rentfile, 0); blockread(rentfile, buf^, count); blockwrite(trent, buf^, count); freemem(buf, count*idxtypesize); end; count := filesize(rentfile) - count - 1; if count > 0 then begin getmem(buf, count*idxtypesize); seek(rentfile, delindex + 1); blockread(rentfile, buf^, count); blockwrite(trent, buf^, count); freemem(buf, count*idxTypesize); end; result := IOResult = 0; if result then begin CloseFile(trent); CloseFile(rentfile); Erase(rentfile); Rename(trent, rentfilename); AssignFile(rentfile, rentfilename); Reset(rentfile); end; result := IOresult = 0; end; begin MaxFilterCount := Sizeof(THomeInfo) div 4; end. Informf.pas Khung trao ñoåi duøng ñeå thoâng baùo loãi hoaëc cho ngöôøi duøng thaáy moät thoâng tin naøo ñoù. (* informf.pas Written by Le Tuan *) unit informf; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ShdWin, ExtCtrls, Tranbtn, StdCtrls; type TInfoForm = class(TShdwin) Label1: TLabel; OK: TLTBtn; Bevel1: TBevel; LTBtn2: TLTBtn; procedure FormPaint(Sender: TObject); procedure OKClick(Sender: TObject); procedure LTBtn2Click(Sender: TObject); private { Private declarations } public { Public declarations } // isConfirm : Boolean; end; function ShowInfo(s : string; isConfirm : Boolean) : integer; implementation {$R *.DFM} uses nhaf; function ShowInfo(s : string; isConfirm : Boolean) : integer; begin with TInfoForm.Create(ChatForm) do begin Label1.Caption := s; if isConfirm then begin OK.Left := 70; LTBtn2.Visible := true; end else begin LTBtn2.Visible := false; OK.Left := 77; end; result := ShowModal; Release; end; end; procedure TInfoForm.FormPaint(Sender: TObject); begin Chatform.PaintBack(Canvas, ChatForm.Image4.Picture.Bitmap); end; procedure TInfoForm.OKClick(Sender: TObject); begin Close; ModalResult := mrOK; end; procedure TInfoForm.LTBtn2Click(Sender: TObject); begin Close; ModalResult := mrCancel; end; end. InputThuef.pas Khung trao ñoåi cho pheùp khaùch haøng nhaäp thôøi gian ngaøy thueâ nhaø. (* inputthuef.pas Written by Le Tuan *) unit inputthuef; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Tranbtn, StdCtrls, ComCtrls, VNForm; type TInputThue = class(TVNForm) DateTimePickerDau: TDateTimePicker; Label1: TLabel; Label2: TLabel; DateTimePickerCuoi: TDateTimePicker; OK: TLTBtn; LTBtn2: TLTBtn; procedure FormPaint(Sender: TObject); procedure LTBtn2Click(Sender: TObject); procedure OKClick(Sender: TObject); private { Private declarations } public { Public declarations } end; implementation {$R *.DFM} uses nhaf; procedure TInputThue.FormPaint(Sender: TObject); begin ChatForm.PaintBack(Canvas, Chatform.Image1.Picture.Bitmap); end; procedure TInputThue.LTBtn2Click(Sender: TObject); begin Close; ModalResult := mrCancel; end; procedure TInputThue.OKClick(Sender: TObject); begin Close; ModalResult := mrOK; end; end. MytdRTF.pas MytdRTF.pas laø moät thö vieän caùc haøm duøng vaøo vieäc hieän thò thoâng tin veà nhaø cöûa ra moät memo daïng RichTextFormat. (* mytdrtf.pas Written by Le Tuan *) unit mytdrtf; interface uses Classes, SysUtils, HomeTools; procedure RecToRTF(Home : THomeInfo; var rtf : TMemoryStream); implementation const header : pchar = '{\rtf1\ansi\deff4\deflang1033\deftab10' + '{\fonttbl' + '{\f0\froman Vietnam;}' + '{\f1\froman thanhoa;}' + '{\f2\fcharset2 Wingdings;}' + '{\f3\froman VNI-FreeWrite\tlul;}' + '{\f4\fnil\fprq2 VNI Times;}' + '}' + '{\colortbl\red54\green80\blue252;' + '\red0\green128\blue0;' + '\red0\green0\blue255;' + '\red43\green10\blue10;' + '\red0\green0\blue0;}'; sTen_F : pchar = '\plain\cf4\fs18\f0\b '; sTen : pchar = '\par\plain\cf4\fs18\f0\b '; sGiaTri : pchar = '\pard\tx1950\tab \plain\cf4\fs18\f0 '; TenNha : pchar = 'Tˆn nh…'; CapNha : pchar = 'Cãp nh…'; ChieuDai : pchar = 'Chi‹u d…i'; ChieuRong : pchar = 'Chi‹u r›ng'; TangLau : pchar = 'S– täng läu'; PhongKhach : pchar = 'S– ph•ng khÿch'; PhongNgu : pchar = 'S– ph•ng ngœ'; PhongTam : pchar = 'S– ph•ng tém'; DiaChi : pchar = '®«a ch©'; Duong : pchar = 'Tˆn ­Ÿõng'; ThanhPho : pchar = 'Tˆn th…nh ph–'; Quan : pchar = 'Tˆn quçn'; NhaChoThue : pchar = 'Nh… thuˆ'; GiaMoiThang : pchar = 'Giÿ thuˆ mši thÿng'; NhaBan : pchar = 'Nh… bÿn'; TriGia : pchar = 'Tr« giÿ cèn nh…'; NhaNgoaiThanh : pchar = 'Nh… ngoâi th…nh'; CoNuocMay : pchar = 'Nh… c¢ nŸôc mÿy'; NhaCoHeThongNuocNong : pchar = 'H¬ th–ng nŸôc n¢ng'; NhaCoHoBoi : pchar = 'Nh… c¢ h˜ bói'; NhaCoNuocGieng : pchar = 'Nh… c¢ nŸôc gi‰ng'; NhaTrongHem : pchar = 'Nh… trong hm'; ChieuRongHem : pchar = 'Chi‹u r›ng hm'; VaoHemBaosau : pchar = 'Chi‹u sƒu hm'; NamXayDung : pchar = 'Nèm xƒy d¨ng'; TinhTrangNha : pchar = 'Tnh trâng nh…'; TrangTriNoiThat : pchar = 'Trang tr¡ n›i thãt'; NhaCoVuon : pchar = 'Nh… c¢ vŸõn'; ChieuRongVuon : pchar = 'Chi‹u r›ng vŸõn'; HuongNha : pchar = 'HŸông nh…'; ChuQuyen : pchar = 'Chœ quy‹n nh… cãp'; NgayThueDau : pchar = 'Ngay bét ­äu thuˆ'; NgayThueCuoi : pchar = 'Ngay thuˆ cu–i c—ng'; procedure WriteEOFRTF(var rtf : TMemoryStream); var c : char; begin c := '}'; rtf.Write(c, 1); end; procedure RecToRTF(Home : THomeInfo; var rtf : TMemoryStream); const noyes : array[Boolean] of pchar = ( 'Kh“ng', 'C¢' ); saidung : array[Boolean] of pchar = ( 'Sai', '®£ng' ); sTinhtrang : array[0..3] of pchar = ( 'Rãt t–t', 'T–t', 'Trung bnh', 'K‚m' ); sTrangTriNoiThat : array[0..3] of pchar = ( 'Sang tr”ng', 'T–t', 'Trung bnh', 'K‚m' ); sHuongNha : array[0..7] of pchar = ( '®“ng', 'Tƒy', 'Nam', 'Béc', '®“ng béc', '®“ng nam', 'Tƒy béc', 'Tƒy nam' ); sCapChuQuyen : array[0..3] of pchar = ( 'Cãp th…nh ph–', 'Cãp quçn', 'Cãp phŸõng', 'Kh“ng giãy' ); snoinfo : pchar = 'Kh“ng c¢ th“ng tin'; procedure WriteRTF(ten, giatri : pchar; f : boolean); begin if f then rtf.Write(sTen_f^, strlen(sTen_f)) else rtf.Write(sTen^, strlen(sTen)); rtf.Write(Ten^, strlen(Ten)); rtf.Write(sGiaTri^, strlen(sGiaTri)); if giatri[0] '-' then rtf.Write(giatri^, length(giatri)) else rtf.Write(snoinfo^, strlen(snoinfo)) end; begin rtf.Write(header^, strlen(header)); WriteRTF(TenNha, @Home.TenNha[1], true); WriteRTF(DiaChi, @Home.Diachi[1], false); WriteRTF(Duong, @Home.Duong[1], false); WriteRTF(NhaNgoaiThanh, saidung[Home.NhaNgoaiThanh], false); WriteRTF(ThanhPho, @Home.ThanhPho[1], false); WriteRTF(Quan, @Home.Quan[1], false); WriteRTF(NhaTrongHem, saidung[Home.NhaTrongHem], false); WriteRTF(ChuQuyen, sCapChuQuyen[Home.ChuQuyen], false); WriteRTF(CapNha, @IntToStr(Home.CapNha)[1], false); WriteRTF(ChieuDai, @myRealToStr(Home.ChieuDai)[1], false); WriteRTF(ChieuRong, @myRealToStr(Home.ChieuRong)[1], false); WriteRTF(TangLau, @IntToStr(Home.TangLau)[1], false); WriteRTF(PhongKhach, @IntToStr(Home.PhongKhach)[1], false); WriteRTF(PhongNgu, @IntToStr(Home.PhongNgu)[1], false); WriteRTF(PhongTam, @IntToStr(Home.PhongTam)[1], false); WriteRTF(NhaChoThue, noyes[Home.NhaChoThue], false); WriteRTF(GiaMoiThang, @myRealToStr(Home.GiaMoithang)[1], false); WriteRTF(NhaBan, noyes[Home.NhaBan], false); WriteRTF(TriGia, @myRealToStr(Home.TriGia)[1], false); WriteRTF(CoNuocMay, noyes[Home.CoNuocMay], false); WriteRTF(NhaCoHeThongNuocNong, noyes[ Home.NhaCoHeThongNuocNong], false); WriteRTF(NhaCoHoBoi, noyes[Home.NhaCoHoBoi], false); WriteRTF(NhaCoNuocGieng, noyes[Home.NhaCoNuocGieng], false); WriteRTF(ChieuRongHem, @myRealToStr(Home.ChieuRongHem)[1], false); WriteRTF(VaoHemBaosau, @myRealToStr(Home.VaoHemBaoSau)[1], false); WriteRTF(NamXayDung, @DateToStr(Home.NamXayDung)[1], false); WriteRTF(TinhTrangNha, sTinhTrang[Home.TinhTrangNha], false); WriteRTF(TrangTriNoiThat, sTrangTriNoithat[ Home.TrangTriNoiThat], false); WriteRTF(NhaCoVuon, noyes[Home.NhaCoVuon], false); WriteRTF(ChieuRongVuon, @myRealToStr(Home.ChieuRongVuon)[1], false); WriteRTF(HuongNha, sHuongNha[Home.HuongNha], false); WriteRTF(NgayThueDau, @DateToStr(Home.NgayDauThue)[1], false); WriteRTF(NgayThueCuoi, @DateToStr(Home.NgayCuoiThue)[1], false); WriteEOFRTF(rtf); rtf.seek(0, 0); end; end. MyThread.pas MyThread.pas laø moät thö vieän chöùa caùc lôùp TThread nhö : TInsertDataThread, TMuaNhaThread… (* myThread.pas Written by Le Tuan *) unit myThread; interface uses Classes, Windows, hometools, SysUtils, Forms, dialogs; type TInsertDataThread = class(TThread) private FHome : THomeInfo; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Home : THomeInfo); end; TModifyDataThread = class(TThread) private FHome : THomeInfo; FIndex : Longint; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint; Home : THomeInfo); end; TMuaNhaThread = class(TThread) private FIndex : Longint; procedure DoThread; protected procedure Execute; override; public constructor Create(Index: Longint); end; TThueNhaThread = class(TThread) private FIndex : Longint; FNgayDauThue, FNgayCuoiThue : TDateTime; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Index: Longint; NgayDauThue, NgayCuoiThue : TDateTime); end; THomeGetThread = class(TThread) private FIndex : longint; FIsServer : Boolean; FClient : Integer; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint; IsServer : Boolean; Client : Integer); end; THomeSearchTextThread = class(TThread) private FName : string; FIsServer : Boolean; FClient : Integer; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Name : string; IsServer : Boolean; Client : Integer); end; THomeGetFilterThread = class(TThread) private FIndex : longint; FIsServer : Boolean; FClient : Integer; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint; IsServer : Boolean; Client : Integer); end; THomeGetDataThread = class(TThread) private FIndex : longint; FIsServer : Boolean; FClient : Integer; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint; IsServer : Boolean; Client : Integer); end; TFindThread = class(TThread) private FFilter : PArrInt; FFind : TFind; FClient : Integer; FFilterCount : Longint; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Find : TFind; Client : Integer); end; TDeleteThread = class(TThread) private FIndex : Longint; procedure DoTerminate; override; procedure DoThread; protected procedure Execute; override; public constructor Create(Index: Longint); end; THomeRentGetDataThread = class(TThread) private FIndex : longint; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint); end; TUnRentThread = class(TThread) private FIndex : Longint; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint); end; THomeSellGetDataThread = class(TThread) private FIndex : longint; procedure DoThread; protected procedure Execute; override; public constructor Create(Index : longint); end; THomeRentCountThread = class(TThread) private procedure DoThread; protected procedure Execute; override; public constructor Create; end; THomeSellCountThread = class(TThread) private procedure DoThread; protected procedure Execute; override; public constructor Create; end; implementation { Important: Methods and properties of objects in VCL can only be used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure ModifyDataThread.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; } uses nhaf, repthuef; procedure myDelay(x : longint); var y : longint; begin y := GetTickCount; repeat Application.ProcessMessages; until GetTickCount > y + x; end; { TInsertDataThread } constructor TInsertDataThread.Create; begin FreeOnTerminate := True; FHome := Home; inherited Create(False); end; procedure TInsertDataThread.DoThread; begin ChatForm.InsertData(FHome); end; procedure TInsertDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure TInsertDataThread.DoTerminate; begin inherited; end; {TModifyDataThread} constructor TModifyDataThread.Create; begin FreeOnTerminate := True; FIndex := Index; FHome := Home; inherited Create(False); end; procedure TModifyDataThread.DoThread; begin ChatForm.ModifyData(FIndex, FHome); end; procedure TModifyDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure TModifyDataThread.DoTerminate; begin inherited; end; {TMuaNhaThread} constructor TMuaNhaThread.Create; begin FreeOnTerminate := True; FIndex := Index; inherited Create(False); end; procedure TMuaNhaThread.DoThread; begin ChatForm.MuaNha(FIndex); end; procedure TMuaNhaThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; {TThueNhaThread} constructor TThueNhaThread.Create; begin FreeOnTerminate := True; FIndex := Index; FNgayDauThue := NgayDauThue; FNgayCuoiThue := NgayCuoiThue; inherited Create(False); end; procedure TThueNhaThread.DoThread; begin ChatForm.ThueNha(FIndex, FNgayDauThue, FNgayCuoiThue); end; procedure TThueNhaThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure TThueNhaThread.DoTerminate; begin inherited; end; {THomeGetThread} constructor THomeGetThread.Create; begin FreeOnTerminate := True; FIndex := Index; FIsServer := IsServer; FClient := Client; inherited Create(False); end; procedure THomeGetThread.DoThread; var x : xxType; begin ChatForm.ffHome := ChatForm.HomeData.HomeGet(FIndex); if not FIsServer then begin FillChar(x, sizeof(x), 0); StrCopy(x.mess, idSetItem); x.Home := ChatForm.ffHome; ChatForm.ServerSocket.Socket.Connections[FClient].SendBuf(x, sz); end; end; procedure THomeGetThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure THomeGetThread.DoTerminate; begin inherited; end; {THomeSearchTextThread} constructor THomeSearchTextThread.Create; begin FreeOnTerminate := True; FName := Name; FIsServer := IsServer; FClient := Client; inherited Create(False); end; procedure THomeSearchTextThread.DoThread; var x : xxType; found : boolean; begin ChatForm.fIndex := ChatForm.HomeData.HomeSearch(Pchar(FName), found); if not FIsServer then begin FillChar(x, sizeof(x), 0); StrCopy(x.mess, idSetIndex); x.index := ChatForm.fIndex; ChatForm.ServerSocket.Socket.Connections[FClient].SendBuf(x, sz); end end; procedure THomeSearchTextThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure THomeSearchTextThread.DoTerminate; begin inherited; end; {THomeGetFilterThread} constructor THomeGetFilterThread.Create; begin FreeOnTerminate := True; FIndex := Index; FIsServer := IsServer; FClient := Client; inherited Create(False); end; procedure THomeGetFilterThread.DoThread; var x : xxType; begin ChatForm.ffHome := ChatForm.HomeData.HomeGet(FIndex); if not FIsServer then begin FillChar(x, sizeof(x), 0); StrCopy(x.mess, idSetItemfilter); x.Home := ChatForm.ffHome; ChatForm.ServerSocket.Socket.Connections[FClient].SendBuf(x, sz); end; end; procedure THomeGetFilterThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure THomeGetFilterThread.DoTerminate; begin inherited; end; {THomeGetDataThread} constructor THomeGetDataThread.Create; begin FreeOnTerminate := True; FIndex := Index; FIsServer := IsServer; FClient := Client; inherited Create(False); end; procedure THomeGetDataThread.DoThread; var x : xxType; begin ChatForm.fHome := ChatForm.HomeData.HomeGet(FIndex); if not FIsServer then begin FillChar(x, sizeof(x), 0); StrCopy(x.mess, idSetData); x.Home := ChatForm.fHome; ChatForm.ServerSocket.Socket.Connections[FClient].SendBuf(x, sz); end; end; procedure THomeGetDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure THomeGetDataThread.DoTerminate; begin inherited; end; { TFindThread } constructor TFindThread.Create; begin FreeOnTerminate := True; FFind := Find; FClient := Client; inherited Create(False); end; procedure TFindThread.DoThread; var x : xxType; begin FFilterCount := ChatForm.HomeData.HomeGetCount; Getmem(FFilter, FFilterCount * sizeof(longint)); ChatForm.HomeData.HomeFind(FFind.ThueBan, FFind.NgoaiNoiThanh, FFind.TriGiaMin, FFind.TriGiaMax, FFind.DienTichMin, FFind.DienTichMax, FFilter, FFilterCount); FillChar(x, sizeof(x), 0); x.index := FFilterCount; StrCopy(x.mess, idFindResult); move(FFilter^, x.Home, FFilterCount * sizeof(longint)); ChatForm.ServerSocket.Socket.Connections[FClient].SendBuf(x, sz); Freemem(FFilter); end; procedure TFindThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure TFindThread.DoTerminate; begin inherited; end; {TDeleteThread} constructor TDeleteThread.Create; begin FreeOnTerminate := True; FIndex := Index; inherited Create(False); end; procedure TDeleteThread.DoThread; begin ChatForm.DeleteNha(FIndex); end; procedure TDeleteThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; procedure TDeleteThread.DoTerminate; begin inherited; end; {THomeRentGetDataThread} constructor THomeRentGetDataThread.Create; begin FreeOnTerminate := True; FIndex := Index; inherited Create(False); end; procedure THomeRentGetDataThread.DoThread; begin RepThueForm.fHome := ChatForm.HomeData.HomeGetRent(FIndex); end; procedure THomeRentGetDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; { TUnRentThread } constructor TUnRentThread.Create; begin FreeOnTerminate := True; FIndex := Index; inherited Create(False); end; procedure TUnRentThread.DoThread; var i, count : integer; fHome : THomeInfo; begin if ChatForm.HomeData.HomeUnRent(FIndex) then begin Count := ChatForm.homeData.HomeGetCount; for i := 0 to ChatForm.ServerSocket.Socket.ActiveConnections - 1 do ChatForm.SendMessageToClient( ChatForm.ServerSocket.Socket.Connections[i], idSetVLBNumItems, Count, fHome); end; end; procedure TUnRentThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; {THomeSellGetDataThread} constructor THomeSellGetDataThread.Create; begin FreeOnTerminate := True; FIndex := Index; inherited Create(False); end; procedure THomeSellGetDataThread.DoThread; begin RepThueForm.fHome := ChatForm.HomeData.HomeGetSell(FIndex); end; procedure THomeSellGetDataThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; {THomeRentCountThread} constructor THomeRentCountThread.Create; begin FreeOnTerminate := True; inherited Create(False); end; procedure THomeRentCountThread.DoThread; begin RepThueForm.fHomeRentCount := ChatForm.HomeData.HomeGetCountRent; end; procedure THomeRentCountThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; {THomeSellCountThread} constructor THomeSellCountThread.Create; begin FreeOnTerminate := True; inherited Create(False); end; procedure THomeSellCountThread.DoThread; begin RepThueForm.fHomeSellCount := ChatForm.HomeData.HomeGetCountSell; end; procedure THomeSellCountThread.Execute; begin EnterCriticalSection(CritSect); Synchronize(DoThread); LeaveCriticalSection(CritSect); end; end. RepThuef.pas Khung trao ñoåi ñeå hieän thò danh saùch caùc nhaø cho thueâ hoaëc möôùn. (* repthuef.pas Written by Le Tuan *) unit repthuef; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, VLB, HomeTools, myThread, Tranbtn, ShadowForm, MyDialog, informf, QFButton; type TRepThueForm = class(TShadowForm) VLB: TVLB; Bevel2: TBevel; Bevel3: TBevel; RichEdit: TRichEdit; Bevel4: TBevel; Label1: TLabel; AdminLTBtnUnThue: TLTBtn; AdminLTBtnCount: TLTBtn; LabelName: TLabel; QFButton1: TQFButton; Bevel1: TBevel; ImageBan: TImage; ImageThue: TImage; procedure VLBGetItem(Sender: TObject; Index: Integer; var ItemString: String); procedure AdminLTBtnUnThueClick(Sender: TObject); procedure FormPaint(Sender: TObject); procedure VLBClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure AdminLTBtnCountClick(Sender: TObject); procedure QFButton1Click(Sender: TObject); private procedure ShowData; function TestTLTBtn(p : TPoint) : boolean; procedure wmNcHitTest(var Msg : TwmNcHitTest); message wm_NcHitTest; public fHome : THomeInfo; isThue : Boolean; fHomeRentCount : longint; fHomeSellCount : longint; end; var RepThueForm: TRepThueForm; implementation {$R *.DFM} uses nhaf, mytdrtf; procedure TRepThueForm.VLBGetItem(Sender: TObject; Index: Integer; var ItemString: String); begin if (index < 0) then exit; if isThue then with THomeRentGetDataThread.Create(Index) do WaitFor else with THomeSellGetDataThread.Create(Index) do WaitFor; ItemString := fHome.TenNha; end; procedure TRepThueForm.AdminLTBtnUnThueClick(Sender: TObject); var index : longint; begin index := VLB.ItemIndex; if (index < 0) or (self = nil) then exit; if ShowInfo( 'Bân c¢ mu–n ­Ÿa nh… n…y v‹ danh sÿch nh… cho thuˆ kh“ng?', true) mrOK then Exit; with TUnRentThread.Create(index) do WaitFor; VLB.NumItems := ChatForm.homeData.HomeGetCountRent; ChatForm.VLB.NumItems := ChatForm.homeData.HomeGetCount; end; procedure TRepThueForm.FormPaint(Sender: TObject); begin ChatForm.PaintBack(Canvas, ChatForm.Image1.Picture.Bitmap); end; procedure TRepThueForm.ShowData; var rtf : TMemoryStream; begin LabelName.Caption := fHome.TenNha; rtf := TMemoryStream.Create; RecToRTF(fHome, rtf); RichEdit.Lines.LoadFromStream(rtf); rtf.Free; end; procedure TRepThueForm.VLBClick(Sender: TObject); var index : longint; begin index := VLB.ItemIndex; if (index < 0) or (self = nil) then begin RichEdit.Clear; Exit; end; if isThue then with THomeRentGetDataThread.Create(Index) do WaitFor else with THomeSellGetDataThread.Create(Index) do WaitFor; ShowData; end; procedure TRepThueForm.FormActivate(Sender: TObject); begin if isThue then begin ImageThue.Visible := true; Caption := 'Th–ng kˆ nh… cho thuˆ'; Label1.Caption := '&Nh… ­á cho thuˆ:'; AdminLTBtnUnThue.Visible := true; AdminLTBtnCount.Hint := 'Th–ng kˆ t™ng s– nh… ­á cho thuˆ'; VLB.NumItems := ChatForm.homeData.HomeGetCountRent; end else begin ImageBan.Visible := true; Caption := 'Th–ng kˆ nh… ­á bÿn'; Label1.Caption := '&Nh… ­á bÿn:'; AdminLTBtnUnThue.Visible := false; AdminLTBtnCount.Hint := 'Th–ng kˆ t™ng s– nh… ­á bÿn'; VLB.NumItems := ChatForm.homeData.HomeGetCountSell; end; VLB.ItemIndex := 0; VLBClick(nil); // NamePanel.Color := rgb(9, 115, 25); end; procedure TRepThueForm.AdminLTBtnCountClick(Sender: TObject); begin if isThue then begin with THomeRentCountThread.Create do WaitFor; ShowInfo('C¢ ' + IntToStr(fHomeRentCount) + ' ng“i nh… ­á cho thuˆ.', false); end else begin with THomeSellCountThread.Create do WaitFor; ShowInfo('C¢ ' + IntToStr(fHomeSellCount) + ' ng“i nh… ­á bÿn.', false); end end; procedure TRepThueForm.QFButton1Click(Sender: TObject); begin Close; ModalResult := mrCancel; end; function TRepThueForm.TestTLTBtn(p : TPoint) : boolean; var i : integer; begin result := false; for i := 0 to ControlCount - 1 do begin if (Controls[i] is TLTBtn) and (PtInRect((Controls[i] as TLTBtn).BoundsRect, p)) then Exit; if (Controls[i] is TQFButton) and (PtInRect((Controls[i] as TQFButton).BoundsRect, p)) then Exit; end; result := true; end; procedure TRepThueForm.wmNcHitTest(var Msg : TwmNcHitTest); begin inherited; if TestTLTBtn(ScreenToClient(Point(Msg.Pos.X, Msg.Pos.Y))) then Msg.Result := HTCAPTION; end; end. ._.

Các file đính kèm theo tài liệu này:

  • docDA0669.doc