หมายเหตุทางเทคนิคนี้อธิบายถึงการสะท้อนความ เป็นคุณลักษณะใหม่ใน MFC 4.0 ยังประกอบด้วยคำแนะนำสำหรับการสร้างตัวควบคุมที่สามารถอย่างง่ายที่ใช้ในการสะท้อนความ?
หมายเหตุทางเทคนิคนี้ไม่กล่าวถึงการสะท้อนความนำไปใช้กับตัวควบคุม ActiveX (เดิมเรียกว่าตัวควบคุม OLE) โปรดดูบทความ ตัวควบคุม ActiveX: ตัวควบคุม Windows SubclassingในVisual c ++ Programmer ของคำแนะนำ?
สะท้อนความคืออะไร?
ตัวควบคุม Windows บ่อยส่งข้อความแจ้งเตือนไปยัง windows หลักของพวกเขา ตัวอย่าง ตัวควบคุมหลายส่งควบคุมสีข้อความแจ้งเตือน (WM_CTLCOLORหรืออย่างใดอย่างหนึ่งของตัวแปร) การปกครองให้ผู้ปกครองต้องจัดหาแปรงสำหรับวาดภาพพื้นหลังของตัวควบคุม?
ใน Windows และ MFC ก่อนการเวอร์ชัน 4.0 หน้าต่างหลัก มักกล่องโต้ตอบ รับผิดชอบในการจัดการกับข้อความเหล่านี้ ซึ่งหมายความ ว่า รหัสสำหรับการจัดการความต้องการอยู่ในชั้นของหน้าต่างหลัก และให้ มีการซ้ำกันในทุกชั้นที่ต้องการในการจัดการกับข้อความ ในกรณีข้างต้น กล่องโต้ตอบทั้งหมดที่ต้องควบคุม ด้วยพื้นหลังแบบกำหนดเองจะมีการจัดการข้อความแจ้งเตือนการควบคุมสี มันจะง่ายเพื่อนำรหัสมาใช้ถ้าห้องควบคุมไม่สามารถถูกเขียนที่จะจัดการกับสีพื้นหลังของตัวเอง?
ใน MFC 4.0 กลไกการเก่าที่ยังคงทำงานได้ หลัก windows สามารถจัดการข้อความแจ้งเตือนได้ นอกจากนี้ อย่างไรก็ตาม MFC 4.0 สะดวกนำมาใช้ใหม่ โดยการนำเสนอคุณลักษณะเรียกว่า "ข้อความสะท้อน" ที่ช่วยให้ข้อความแจ้งเตือนเหล่านี้จะจัดการ ในหน้าต่างควบคุมเด็กหรือหน้าต่างหลัก หรือทั้งสองอย่าง ในตัวควบคุมพื้นหลังสีอย่าง คุณสามารถเดี๋ยวนี้เขียนควบคุมคลาสที่กำหนดสีพื้นหลังของตัวเอง โดยการจัดการข้อความWM_CTLCOLORสะท้อน โดยไม่ต้องมาจากการใช้ไซต์แม่ได้ (โปรดทราบว่า เนื่องจากมีการใช้งานภาพสะท้อนของข้อความ โดย MFC ไม่ โดย Windows คลาสหน้าต่างที่แม่ต้องได้มาจากCWndสำหรับข้อความสะท้อนการทำงาน)
MFC รุ่นเก่าไม่ได้คล้ายการสะท้อนกลับของข้อความ โดยมีฟังก์ชันเสมือนสำหรับข้อความไม่กี่ เช่นข้อความสำหรับกล่องรายการที่วาดเจ้า (WM_DRAWITEMและอื่น ๆ) สะท้อนกลไกใหม่ของข้อความคือ generalized และสอดคล้องกัน?
สะท้อนความไม่เข้ากันได้แบบย้อนหลังกับโค้ดที่เขียนขึ้นสำหรับรุ่น MFC ก่อนหน้าเป็น 4.0?
ถ้าคุณได้ป้อนตัวจัดการเฉพาะข้อความที่ หรือช่วงของข้อความ ในหน้าต่างหลักของคลาส มันจะแทนที่ สะท้อนตัวจัดการข้อความสำหรับข้อความเดียวกัน โดยที่คุณไม่เรียกใช้คลาสพื้นฐานตัวจัดการฟังก์ชันในตัวจัดการของคุณเอง ตัวอย่างเช่น ถ้าคุณสามารถจัดการWM_CTLCOLORในชั้นการกล่องโต้ตอบของคุณ การจัดการของคุณจะแทนใด ๆ ตัวจัดการข้อความที่สะท้อน?
ถ้า ในคลาสหน้าต่างหลักของคุณ คุณสามารถใส่ตัวจัดการข้อความWM_NOTIFYที่ระบุหรือช่วงของข้อความWM_NOTIFYจะเรียกตัวจัดการของคุณเท่านั้นถ้าตัวควบคุมเด็กที่ส่งข้อความเหล่านั้นไม่มีตัวจัดการข้อความที่สะท้อนผ่านON_NOTIFY_REFLECT() ถ้าคุณใช้ON_NOTIFY_REFLECT_EX()ในการแมปข้อความของคุณ ตัวจัดการข้อความของคุณอาจ หรืออาจไม่อนุญาตให้หน้าต่างหลักการจัดการกับข้อความ ถ้าตัวจัดการส่งกลับค่าTRUEข้อความจะถูกจัดการ โดยแม่ดี ในขณะที่การโทรที่ส่งกลับค่าเท็จไม่อนุญาตให้แม่เพื่อจัดการกับมัน โปรดสังเกตว่า ข้อความที่สะท้อนจะจัดการก่อนข้อความแจ้งเตือน?
เมื่อมีส่งข้อความWM_NOTIFYตัวควบคุมถูกเสนอโอกาสแรกเพื่อจัดการกับมัน ถ้ามีส่งข้อความสะท้อนอื่น ๆ หน้าต่างหลักมีโอกาสแรกเพื่อจัดการกับมัน และตัวควบคุมจะได้รับข้อความที่สะท้อน เมื่อต้องการทำเช่นนั้น จำเป็นต้องจัดการฟังก์ชันและรายการในตัวควบคุมคลาแผนที่ความเหมาะสม?
แมโครแผนผังข้อความสำหรับข้อความที่สะท้อนเป็นเล็กน้อยแตกต่างจากการแจ้งเตือนที่ปกติ: มี_REFLECTถูกผนวกเข้ากับชื่อของปกติ ตัวอย่าง การจัดการข้อความWM_NOTIFYในปกครอง คุณต้องใช้แมโคON_NOTIFYในการแมปข้อความของผู้ปกครอง การจัดการข้อความในตัวควบคุมลูกสะท้อน ใช้แมโคON_NOTIFY_REFLECTในการแมปข้อความของตัวควบคุมลูก ในบางกรณี พารามิเตอร์จะแตกต่าง ดี หมายเหตุว่า ClassWizard สามารถมักจะเพิ่มรายการข้อความแผนที่สำหรับคุณ และให้การใช้งานฟังก์ชันโครงกระดูกกับพารามิเตอร์ที่ถูกต้อง?
ดูTN061: ON_NOTIFY ข้อ ความ WM_NOTIFY และสำหรับข้อมูลเกี่ยวกับข้อความใหม่ของWM_NOTIFY?
ข้อความแผนผังรายการและแบบตัวฟังก์ชันการจัดการสำหรับข้อความที่สะท้อน
การจัดการข้อความแจ้งเตือนของตัวควบคุมที่สะท้อน ใช้แมโครของข้อความแผนผังและแบบตัวฟังก์ชันที่แสดงในตารางด้านล่างนี้?
ClassWizard สามารถเพิ่มรายการข้อความแผนผังเหล่านี้สำหรับคุณโดยปกติ และให้ใช้งานฟังก์ชันโครงกระดูก ดู การกำหนดตัวจัดการข้อความสำหรับข้อความสะท้อนให้เห็นในVisual c ++ Programmer ของคู่มือสำหรับข้อมูลเกี่ยวกับวิธีการกำหนดตัวจัดการสำหรับแสดงข้อความ?
การแปลงจากชื่อข้อความชื่อแมโครสะท้อน prepend ON_และผนวก_REFLECT ตัวอย่างเช่นWM_CTLCOLORกลายเป็นON_WM_CTLCOLOR_REFLECT (เมื่อต้องการดูข้อความที่สามารถมีผล ทำการแปลงที่ตรงกันข้ามในรายการแมโครในตารางด้านล่างนี้)
ยกเว้นสำหรับกฎข้างต้นที่สามมีดังนี้:
ในแต่ละกรณีพิเศษข้างต้น คุณต้องระบุชื่อของฟังก์ชันการจัดการสมาชิก ในกรณีอื่น ๆ คุณต้องใช้ชื่อมาตรฐานสำหรับฟังก์ชันการจัดการของคุณ?
ในความหมายของพารามิเตอร์และค่าที่ส่งกลับของฟังก์ชันเป็นเอกสารภายใต้ชื่อฟังก์ชันหรือชื่อฟังก์ชันกับบนซึ่ง ตัวอย่างCtlColorมีการระบุไว้ในOnCtlColor ตัวจัดการข้อความที่สะท้อนหลายพารามิเตอร์ที่น้อยลงกว่าตัวจัดการที่คล้ายคลึงกันในหน้าต่างหลักนั้น เพียงแค่ตรงกับชื่อในตารางด้านล่างกับชื่อของพารามิเตอร์ในเอกสารอย่างเป็นทางการ?
| แผนผังรายการ | ฟังก์ชันแบบตัวอย่าง |
| ON_CONTROL_REFLECT ( wNotifyCode, memberFxn ) | afx_msg โมฆะmemberFxn ( ); |
| ON_NOTIFY_REFLECT ( wNotifyCode, memberFxn ) | afx_msg โมฆะmemberFxn(NMHDR * pNotifyStruct, LRESULT *ผล ); |
| ON_UPDATE_COMMAND_UI_REFLECT ( memberFxn ) | afx_msg โมฆะmemberFxn(CCmdUI * pCmdUI ); |
| ON_WM_CTLCOLOR_REFLECT () | afx_msg HBRUSH CtlColor (CDC * pDC, UINT nCtlColor ); |
| ON_WM_DRAWITEM_REFLECT () | afx_msg โมฆะ DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct ); |
| ON_WM_MEASUREITEM_REFLECT () | afx_msg โมฆะ MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct ); |
| ON_WM_DELETEITEM_REFLECT () | afx_msg โมฆะ DeleteItem (LPDELETEITEMSTRUCT lpDeleteItemStruct ); |
| ON_WM_COMPAREITEM_REFLECT () | afx_msg int CompareItem (LPCOMPAREITEMSTRUCT lpCompareItemStruct ); |
| ON_WM_CHARTOITEM_REFLECT () | afx_msg int CharToItem (UINT nKey, UINT nIndex ); |
| ON_WM_VKEYTOITEM_REFLECT () | afx_msg int VKeyToItem (UINT nKey, UINT nIndex ); |
| ON_WM_HSCROLL_REFLECT () | afx_msg โมฆะ HScroll (UINT nSBCode, UINT nPos ); |
| ON_WM_VSCROLL_REFLECT () | afx_msg โมฆะ VScroll (UINT nSBCode, UINT nPos ); |
| ON_WM_PARENTNOTIFY_REFLECT () | afx_msg โมฆะ ParentNotify (UINT ข้อความLPARAM lParam ); |
แมโคON_NOTIFY_REFLECTและON_CONTROL_REFLECTมีรูปแบบต่าง ๆ ที่ทำให้วัตถุมากกว่าหนึ่ง (เช่นตัวควบคุมและแม่ของ) เพื่อจัดการกับข้อความกำหนดให้?
| แผนผังรายการ | ฟังก์ชันแบบตัวอย่าง |
| ON_NOTIFY_REFLECT_EX ( wNotifyCode, memberFxn ) | afx_msg BOOLmemberFxn(NMHDR * pNotifyStruct, LRESULT *ผล ); |
| ON_CONTROL_REFLECT_EX ( wNotifyCode, memberFxn ) | afx_msg BOOLmemberFxn ( ); |
การจัดการข้อความการ Reflected: ตัวอย่างของตัวควบคุมที่สามารถ
ตัวอย่างง่าย ๆ นี้สร้างตัวควบคุมที่สามารถเรียกว่า CYellowEdit ควบคุมการทำงานเหมือนกับตัวควบคุมการแก้ไขทั่วไปยกเว้นว่าจะแสดงข้อความสีดำบนพื้นหลังสีเหลือง มันจะง่ายต่อการเพิ่มฟังก์ชันของสมาชิกที่จะอนุญาตให้มีการ CYellowEdit ควบคุมการแสดงสีที่แตกต่างกัน?
เมื่อต้องการลองอย่างนี้ ทำขั้นตอนต่อไปนี้:
คุณต้องมีโปรแกรมประยุกต์ที่จะพัฒนาตัวควบคุมที่สามารถ ถ้าคุณไม่มีโปรแกรมประยุกต์ที่มีอยู่ใช้ สร้างในโปรแกรมประยุกต์แบบโต้ตอบโดยใช้ AppWizard?
CYellowEdit ยึดCEdit ปล่อยให้กล่อง "เพิ่มไปยังคอมโพเนนต์ Gallery" การตรวจสอบ?CYellowEdit คลา สองข้อแรกจะCOLORREFตัวแปรเพื่อเก็บสีข้อความและสีพื้นหลัง ที่สามจะเป็นวัตถุCBrushซึ่งจะเก็บแปรงสำหรับวาดภาพพื้นหลัง วัตถุCBrushช่วยให้คุณ สามารถสร้างการอ้างอิงหนึ่งครั้ง แต่ถึงจะหลังจากที่แปรง และทำลาย'แปรง'โดยอัตโนมัติเมื่อตัว CYellowEdit ควบคุมถูกทำลาย?CYellowEdit::CYellowEdit()
{
m_clrText = RGB (0, 0, 0);
m_clrBkgnd = RGB (255, 255, 0);
m_brBkgnd.CreateSolidBrush (m_clrBkgnd);
}
CYellowEdit คลา โปรดสังเกตว่า เครื่องหมายเท่ากับด้านหน้าของชื่อข้อความในรายการข้อความที่คุณสามารถจัดการสิ่งบ่งชี้ว่า ข้อความจะสะท้อนให้เห็น คำอธิบายใน การกำหนดตัวจัดการข้อความสำหรับข้อความสะท้อนให้เห็นในรายการแนะนำของ Visual c ++ Programmer ของ?ClassWizard เพิ่มต่อไปนี้ข้อความแผนที่แมโครและโครงสร้างฟังก์ชันที่คุณ:
ON_WM_CTLCOLOR_REFLECT()
/ / หมายเหตุ: รหัสอื่น ๆ จะเป็นระหว่าง....
HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) {
/ / TODO: เปลี่ยนแอตทริบิวต์ใด ๆ ของ DC ได้ที่นี่
/ / TODO: กลับแปรงไม่ใช่ NULL ถ้า
/ / ตัวจัดการผู้ปกครองไม่ควรเรียก
ส่งกลับค่า NULL
}
pDC-gtSetTextColor (m_clrText); / / ข้อความ
pDC - > SetBkColor (m_clrBkgnd); / / bkgnd ข้อความ
กลับ m_brBkgnd / / ctl bkgnd
CYellowEdit ควบคุมในกล่องโต้ตอบของส่วนหัวของแฟ้ม?CYellowEdit ควบคุมคลาสกับโครงการอื่น ๆ?หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)