Delphi เป็นเครื่องมือพัฒนาการเขียนโปรแกรม WINDOWS ใหม่ล่าสุดที่ Borland มอบให้ เนื่องจากใช้ภาษา Pascal เชิงวัตถุที่ยืดหยุ่นและสามารถนำมาใช้ซ้ำได้ และมีกลไกฐานข้อมูล (BDE) ที่ทรงพลัง โค้ดที่รวดเร็ว คอมไพเลอร์ยังให้คุณสมบัติที่ยอดเยี่ยมมากมาย ส่วนประกอบต่างๆ เป็นที่ชื่นชอบของโปรแกรมเมอร์ส่วนใหญ่ มีความโดดเด่นจากภาษาโปรแกรมต่างๆ มากมาย (เช่น VB, PowerBuilder, Powerpoint เป็นต้น)
ข้อดีอย่างหนึ่งของ DELPHI เหนือภาษาการเขียนโปรแกรมอื่นๆ (เช่น VB4.0) คือสามารถปรับแต่งข้อความใน DELPHI และสามารถประมวลผลได้โดยตรง สำหรับผู้ที่ต้องการเขียนส่วนประกอบของตนเอง (Component) หรือผู้ที่ต้องการสกัดกั้นและกรองข้อความ เป็นสิ่งสำคัญสำหรับผู้ใช้ เนื่องจากโดยทั่วไปการเขียนส่วนประกอบจำเป็นต้องมีการประมวลผลข้อความที่เกี่ยวข้อง ต่อไปนี้เป็นคำแนะนำเกี่ยวกับกลไกการประมวลผลข้อความใน Delphi
1. การส่งข้อความใน DELPHI VCL
ส่วนประกอบ VCL (Visual Component Library) แต่ละตัว (เช่น Tbutton, Tedit เป็นต้น) มีกลไกการประมวลผลข้อความโดยธรรมชาติ ประเด็นพื้นฐานคือคลาสส่วนประกอบจะได้รับข้อความบางอย่างและส่งไปยังวิธีการประมวลผลที่เหมาะสม หากมี ไม่มีวิธีการประมวลผลเฉพาะ เรียกว่าหมายเลขอ้างอิงการประมวลผลข้อความเริ่มต้น ในหมู่พวกเขา mainwndPRoc เป็นวิธีการคงที่ที่กำหนดไว้ในคลาส Twincontrol และไม่สามารถโอเวอร์โหลดได้ (แทนที่) มันไม่ได้ประมวลผลข้อความโดยตรง แต่ปล่อยให้เมธอด wndproc สำหรับการประมวลผล และจัดเตรียมโมดูลการจัดการข้อยกเว้นสำหรับเมธอด wndproc เมธอด Mainwndproc มีการประกาศดังนี้:
ขั้นตอน MainWndProc (ข้อความ var: TMessage);
Wndproc เป็นวิธีการเสมือนที่กำหนดไว้ในคลาส Tcontrol ซึ่งเรียกวิธีการจัดส่งเพื่อกระจายข้อความ วิธีการ wndproc มีการประกาศดังต่อไปนี้:
ขั้นตอน WndProc (ข้อความ var: TMessage);
วิธีการจัดส่งถูกกำหนดไว้ในคลาสรูทของ Tobject และมีการประกาศดังต่อไปนี้:
ขั้นตอน Tobject.dispatch(var Message); พารามิเตอร์ข้อความที่ส่งไปยังการจัดส่งจะต้องเป็นประเภทบันทึกและจุดเข้าแรกในบันทึกนี้จะต้องเป็นฟิลด์ประเภทคาร์ดินัล (ฟิลด์) ซึ่งมีข้อความของข้อความที่จะแจกจ่ายหมายเลข . ตัวอย่างเช่น:
พิมพ์
Tmessage=บันทึก
ข่าวสารเกี่ยวกับ: พระคาร์ดินัล;
wparam:คำ;
lparam:longint;
ผลลัพธ์:ลองจินต์;
จบ;
เมธอด Dispatch จะเรียกเมธอด handle ของคลาสรุ่นสุดท้ายของคอมโพเนนต์ที่จัดการข้อความนี้ตามหมายเลขข้อความ หากไม่มีตัวจัดการที่สอดคล้องกับข้อความนี้ในคอมโพเนนต์นี้และคลาสบรรพบุรุษของเมธอด Dispatch จะเรียก Defaulthandler วิธีการ Defaulthandler คือ วิธีการเสมือนที่กำหนดไว้ใน Tobject มีการประกาศดังต่อไปนี้:
ขั้นตอน Defaulthandler (ข้อความ var); เสมือน;
เมธอด Defaulthandler ในคลาส Tobject จะใช้การส่งคืนแบบธรรมดาเท่านั้นโดยไม่มีการประมวลผลข้อความใดๆ เราสามารถใช้การประมวลผลเริ่มต้นของข้อความในคลาสย่อยได้โดยการโอเวอร์โหลดเมธอดเสมือนนี้ สำหรับส่วนประกอบใน VCL วิธี Defaulthandler จะเริ่มการทำงานของ windows ฟังก์ชัน API Defwindowproc เพื่อประมวลผลข้อความ
2. ตัวจัดการการประมวลผลข้อความใน DELPHI
ใน DELPHI ผู้ใช้สามารถปรับแต่งข้อความและตัวจัดการการประมวลผลข้อความได้ คำจำกัดความของตัวจัดการการประมวลผลข้อความมีหลักการดังต่อไปนี้:
วิธีการจัดการการประมวลผลข้อความต้องเป็นขั้นตอน และสามารถส่งผ่านพารามิเตอร์ตัวแปรชนิด Tmessage ได้เพียงพารามิเตอร์เดียวเท่านั้น
การประกาศวิธีการจะต้องตามด้วยคำสั่งข้อความ ตามด้วยป้ายกำกับข้อความ (ค่าคงที่จำนวนเต็ม) ระหว่าง 0 ถึง 32767
วิธีจัดการข้อความไม่จำเป็นต้องใช้คำสั่งแทนที่เพื่อระบุการแทนที่ตัวจัดการข้อความของบรรพบุรุษอย่างชัดเจน นอกจากนี้ โดยทั่วไปจะมีการประกาศในพื้นที่ที่ได้รับการป้องกันหรือส่วนตัวของส่วนประกอบ
ในการจัดการข้อความ ผู้ใช้โดยทั่วไปจะประมวลผลข้อความก่อน และสุดท้ายใช้คำสั่งที่สืบทอดมาเพื่อเรียกการจัดการที่สอดคล้องกับข้อความนี้ในคลาสบรรพบุรุษ (ในบางกรณี มันอาจจะตรงกันข้าม) เนื่องจากการจัดการการประมวลผลของ ข้อความนี้ในคลาสบรรพบุรุษอาจเป็นชื่อและประเภทพารามิเตอร์ไม่ชัดเจน และการเรียกคำสั่งที่สืบทอดมาสามารถหลีกเลี่ยงปัญหานี้ได้ ในทำนองเดียวกัน หากไม่มีตัวจัดการที่สอดคล้องกับข้อความนี้ในคลาสบรรพบุรุษ ที่สืบทอดมาจะเรียกเมธอด Defaulthandler โดยอัตโนมัติ (แน่นอนว่าถ้าคุณต้องการบล็อกข้อความนี้ ไม่จำเป็นต้องใช้คำสั่งที่สืบทอดมา)
วิธีการจัดการข้อความถูกประกาศเป็น:
ขั้นตอน Mymsgmethod (ข้อความ var: Tmessage ข้อความ Msgtype;
ในทำนองเดียวกัน ผู้ใช้ยังสามารถกำหนดข้อความของตนเองได้ควรเริ่มต้นด้วย WM_USER
ตัวอย่างของข้อความแบบกำหนดเองและตัวจัดการการประมวลผลข้อความมีดังนี้:
const my_paint=Wm_user+1;
พิมพ์
Tmypaint=บันทึก
msgstr:พระคาร์ดินัล;
ขนาด:คำ;
mcolor:longint;
msgresult:longint;
จบ;
พิมพ์
Tmycontrol=คลาส(TCustomControl)
ได้รับการคุ้มครอง
การเปลี่ยนแปลงขั้นตอน (ข้อความ var: Tmypaint); ข้อความ my_paint;
-
จบ;
-
ขั้นตอน Tmycontrol.change (ข้อความ var: Tmypaint);
เริ่ม
ขนาด:=message.msize; {ตั้งค่าแอตทริบิวต์ขนาด Tmybutton}
color:=message.mcolor; {ตั้งค่าแอตทริบิวต์สี Tmybutton}
{ทำอย่างอื่น}
สืบทอดมา { ส่งมอบให้กับ Tcustomcontrol}
จบ;
3. กรองข้อความ
การกรองข้อความเรียกอีกอย่างว่ากับดักข้อความ ในบางกรณี ผู้ใช้อาจต้องบล็อกข้อความบางข้อความหรือสกัดกั้นข้อความบางข้อความเพื่อประมวลผล จากบทนำข้างต้นเราจะเห็นว่าโดยทั่วไปมีสามวิธีในการกรองข้อความ: (1) โอเวอร์โหลดวิธีการเสมือนที่สืบทอดมาจากส่วนประกอบ (2) เขียนตัวจัดการการประมวลผลข้อความสำหรับข้อความบางอย่าง โอเวอร์โหลดเมธอดเสมือน Defhandler ที่สืบทอดมาจากคอมโพเนนต์ โดยที่ข้อความถูกประมวลผล วิธีการที่ใช้บ่อยที่สุดคือวิธีที่ (2) ซึ่งได้แนะนำไปแล้วในส่วนที่แล้ว วิธีที่ (1) คล้ายกับวิธีที่ (3) ในที่นี้เราจะแนะนำวิธีที่ (1) สั้นๆ เท่านั้น
กระบวนการทั่วไปของการโอเวอร์โหลดเมธอดเสมือน wndproc มีดังต่อไปนี้:
ขั้นตอน Tmyobject.wndproc (ข้อความ var: Tmessage);
เริ่ม
{... พิจารณาว่าข้อความนี้ควรได้รับการประมวลผลหรือไม่..}
wndproc ที่สืบทอดมา (ข้อความ);
{ข้อความที่ยังไม่ได้ประมวลผลได้รับการจัดการโดยวิธี wndproc หลัก}
จบ;
จะเห็นได้ว่าข้อดีของการประมวลผลข้อความในเมธอด wndproc คือสามารถกรองข้อความทั้งหมดได้โดยไม่ต้องระบุตัวจัดการการประมวลผลสำหรับแต่ละข้อความ จริงๆ แล้ว มันถูกใช้ในองค์ประกอบ Tcontrol เพื่อกรองและ ประมวลผลข้อความเมาส์ทั้งหมด (จาก WM_mousefirst ถึง WM_mouselast ดังแสดงในโค้ดต่อไปนี้) นอกจากนี้ยังสามารถใช้เพื่อป้องกันไม่ให้ข้อความบางอย่างถูกส่งไปยังตัวจัดการ
ขั้นตอน TControl.WndProc (ข้อความ var: TMessage);
เริ่ม
ถ้า (Message.Msg>=WM_MOUSEFIRST) และ
(ข้อความข่าวสาร <= WM_MOUSELAST)
แล้ว
ถ้าลากแล้ว {จัดการลากเหตุการณ์}
DragMouseMsg(TWMMouse(ข้อความ))
อื่น
... {จัดการข้อความเมาส์อื่น ๆ }
จบ;
จัดส่ง(ข้อความ);
{หรือส่งข้อความตามปกติ}
จบ;
ตัวอย่างต่อไปนี้เป็นตัวอย่างส่วนประกอบแบบกำหนดเองอย่างง่าย:
คลาส Tmyedit เป็นคลาสใหม่ที่ได้รับมาจากคลาส Tedit คุณลักษณะของมันคือไม่สามารถรับโฟกัสระหว่างการดำเนินการและไม่สามารถป้อนข้อมูลด้วยคีย์บอร์ดได้ (ค่อนข้างคล้ายกับส่วนประกอบ Tlabel) เราสามารถกรองข้อความ WM_setfocus และ WM_mousemove ออกไปได้ วิธีการ wndproc และดำเนินการ เพื่อให้บรรลุข้อกำหนดข้างต้น โปรแกรมต้นฉบับจะเป็นดังนี้:
หน่วยมายแก้ไข;
อินเตอร์เฟซ
การใช้งาน
Windows, ข้อความ, SysUtils, คลาส, กราฟิก,
การควบคุม แบบฟอร์ม กล่องโต้ตอบ
StdCtrls;
พิมพ์
Tmyedit = คลาส (TEdit)
ส่วนตัว
{ประกาศส่วนตัว}
ได้รับการคุ้มครอง
{ ประกาศที่ได้รับการคุ้มครอง }
{ ฟิลด์และวิธีการอื่นๆ}
ขั้นตอน wndproc (ข้อความ var: Tmessage); แทนที่;
สาธารณะ
{ประกาศสาธารณะ}
ที่ตีพิมพ์
{ ประกาศที่เผยแพร่ }
จบ;
ขั้นตอนการลงทะเบียน;
การดำเนินการ
ขั้นตอนการลงทะเบียน;
เริ่ม
RegisterComponents('ตัวอย่าง', [Tmyedit]);
จบ;
ขั้นตอน Tmyedit.wndproc (ข้อความ var: tmessage);
เริ่ม
ถ้า message.msg=wm_mousemove แล้ว
เริ่ม
เคอร์เซอร์:=แครโรว์;
{ตั้งค่าเคอร์เซอร์ให้แครโรว์แทนเคอร์เซอร์ crBeam เริ่มต้น}
ออก;
จบ;
ถ้า message.msg=wm_SetFocus ให้ออก
{ป้องกันข้อความ WM_setfocus และป้องกันไม่ให้ตัวควบคุม Tmyedit ได้รับการโฟกัสอินพุต}
wndproc ที่สืบทอดมา (ข้อความ);
{ข้อความอื่นๆ ถูกส่งไปยังผู้ปกครอง wndproc เพื่อประมวลผล}
จบ;
จบ.
คุณสามารถเพิ่ม Tmyedit ลงใน Component Palette เพื่อทดสอบประสิทธิภาพได้
ดังที่เห็นได้จากบทนำข้างต้น เพียงทำความเข้าใจกลไกการประมวลผลข้อความใน Delphi VCL เท่านั้น เชี่ยวชาญวิธีการและเวลาในการประมวลผลข้อความต่างๆ (โดยใช้เครื่องมือต่างๆ หากจำเป็น เช่น winsight32, spy ฯลฯ) และรวมคุณลักษณะต่างๆ ของภาษา OOP เราสามารถรวบรวมส่วนประกอบคุณภาพสูงได้ แน่นอนว่าสิ่งนี้ทำให้ผู้อ่านต้องสำรวจและสั่งสมประสบการณ์ในทางปฏิบัติอย่างต่อเนื่อง