TN062: ภาพสะท้อนข้อความสำหรับตัวควบคุม Windows

หมายเหตุทางเทคนิคนี้อธิบายถึงการสะท้อนความ เป็นคุณลักษณะใหม่ใน 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 ควบคุมการแสดงสีที่แตกต่างกัน?

เมื่อต้องการลองอย่างนี้ ทำขั้นตอนต่อไปนี้:

  1. สร้างกล่องโต้ตอบสร้างในโปรแกรมประยุกต์ที่มีอยู่ สำหรับข้อมูลเพิ่มเติมดูที่ โต้ตอบแก้ไขในVisual c ++คู่มือผู้ใช้?

    คุณต้องมีโปรแกรมประยุกต์ที่จะพัฒนาตัวควบคุมที่สามารถ ถ้าคุณไม่มีโปรแกรมประยุกต์ที่มีอยู่ใช้ สร้างในโปรแกรมประยุกต์แบบโต้ตอบโดยใช้ AppWizard?

  2. กับโครงการของคุณโหลดลงใน Visual c ++ ใช้ ClassWizard สร้างคลาสแบบใหม่ที่เรียกว่า CYellowEdit ยึดCEdit ปล่อยให้กล่อง "เพิ่มไปยังคอมโพเนนต์ Gallery" การตรวจสอบ?

  3. เพิ่มตัวแปรการสมาชิกสามไปของคุณ CYellowEdit คลา สองข้อแรกจะCOLORREFตัวแปรเพื่อเก็บสีข้อความและสีพื้นหลัง ที่สามจะเป็นวัตถุCBrushซึ่งจะเก็บแปรงสำหรับวาดภาพพื้นหลัง วัตถุCBrushช่วยให้คุณ สามารถสร้างการอ้างอิงหนึ่งครั้ง แต่ถึงจะหลังจากที่แปรง และทำลาย'แปรง'โดยอัตโนมัติเมื่อตัว CYellowEdit ควบคุมถูกทำลาย?

  4. การเตรียมใช้งานตัวแปรของสมาชิก โดยการเขียนที่กำหนดดังนี้:
    CYellowEdit::CYellowEdit()
    {
    m_clrText = RGB (0, 0, 0);
    m_clrBkgnd = RGB (255, 255, 0);
    m_brBkgnd.CreateSolidBrush (m_clrBkgnd);
    }
    
  5. การใช้ ClassWizard เพิ่มตัวจัดการข้อความWM_CTLCOLORที่สะท้อนการของ CYellowEdit คลา โปรดสังเกตว่า เครื่องหมายเท่ากับด้านหน้าของชื่อข้อความในรายการข้อความที่คุณสามารถจัดการสิ่งบ่งชี้ว่า ข้อความจะสะท้อนให้เห็น คำอธิบายใน การกำหนดตัวจัดการข้อความสำหรับข้อความสะท้อนให้เห็นในรายการแนะนำของ Visual c ++ Programmer ของ?

    ClassWizard เพิ่มต่อไปนี้ข้อความแผนที่แมโครและโครงสร้างฟังก์ชันที่คุณ:

    ON_WM_CTLCOLOR_REFLECT()
    
    / / หมายเหตุ: รหัสอื่น ๆ จะเป็นระหว่าง....
    
    HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) {
    / / TODO: เปลี่ยนแอตทริบิวต์ใด ๆ ของ DC ได้ที่นี่
    
    / / TODO: กลับแปรงไม่ใช่ NULL ถ้า
    / / ตัวจัดการผู้ปกครองไม่ควรเรียก
    ส่งกลับค่า NULL
    }
    
  6. แทนเนื้อหาของฟังก์ชัน ด้วยรหัสต่อไปนี้ รหัสจะระบุข้อความสี สีพื้นหลังข้อความ และสีพื้นหลังสำหรับส่วนที่เหลือของตัวควบคุม?
    pDC-gtSetTextColor (m_clrText);    / / ข้อความ
    pDC - > SetBkColor (m_clrBkgnd);    / / bkgnd ข้อความ
    กลับ m_brBkgnd                / / ctl bkgnd
    
  7. สร้างตัวควบคุมการแก้ไขในกล่องโต้ตอบของคุณ แล้วแนบกับตัวแปรของสมาชิก โดยการคลิกสองครั้งที่ตัวควบคุมการแก้ไขในขณะที่กดแป้นควบคุมค้างไว้ ในกล่องโต้ตอบเพิ่มตัวแปรสมาชิก เสร็จสิ้นชื่อตัวแปร และเลือก "Control" สำหรับประเภท แล้ว "CYellowEdit" สำหรับชนิดของตัวแปร อย่าลืมตั้งค่าลำดับแท็บในกล่องโต้ตอบ ยัง ให้แน่ใจว่าจะรวมแฟ้มหัวข้อสำหรับการ CYellowEdit ควบคุมในกล่องโต้ตอบของส่วนหัวของแฟ้ม?

  8. สร้าง และเรียกใช้โปรแกรมประยุกต์ของคุณ ตัวควบคุมการแก้ไขจะมีพื้นหลังเป็นสีเหลือง?

  9. ขณะนี้คุณสามารถใช้คอมโพเนนต์ Gallery เพิ่มของคุณ CYellowEdit ควบคุมคลาสกับโครงการอื่น ๆ?

หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)

Index