TN006: ข้อความ Maps

หมายเหตุนี้อธิบายถึงการอำนวยการแมปข้อความของ MFC?

ปัญหา

Microsoft Windows ใช้สารสำคัญเสมือนฟังก์ชันในคลาสหน้าต่างใช้สิ่งอำนวยความสะดวกในการส่งข้อความคืออะไร เนื่องจากการขนาดใหญ่จำนวนข้อความที่เกี่ยวข้อง ให้ฟังก์ชันเสมือนแยกต่างหากสำหรับแต่ละข้อความ Windows ผลลัพธ์ในแบบ vtable prohibitively ขนาดใหญ่?

ยัง เนื่อง จากจำนวนข้อความที่กำหนดโดยระบบ Windows ที่มีการเปลี่ยนแปลงตลอดเวลา และเนื่อง จากโปรแกรมประยุกต์อาจต้องการกำหนดให้ข้อความของ Windows บางอย่างของตัวเอง กลไกในการแมปข้อความให้ระดับของ indirection ที่ป้องกันไม่ให้เปลี่ยนแปลงของอินเทอร์เฟซการแบ่งรหัสที่มีอยู่?

ภาพรวม

MFC แสดงแทนคำสั่งสวิตช์ที่ใช้ในโปรแกรมแบบดั้งเดิมของ Windows เพื่อจัดการกับข้อความที่ส่งไปยังหน้าต่าง การแมปจากข้อความไปยังสมาชิกฟังก์ชันอาจถูกกำหนดดังนั้นเมื่อข้อความจะถูกจัดการ โดยหน้าต่าง ฟังก์ชันที่เหมาะสมจะถูกเรียกโดยอัตโนมัติ สิ่งอำนวยความสะดวกความแผนที่นี้ถูกออกแบบให้คล้ายกับฟังก์ชันที่เสมือน แต่มีคุณประโยชน์เพิ่มเติมที่ไม่เป็นไปได้ ด้วยฟังก์ชันเสมือน c ++?

การกำหนดแผนผังของข้อความ

แมโคDECLARE_MESSAGE_MAPประกาศสมาชิกสามสำหรับคลาส?

แมโครนี้ควรถูกวางในการประกาศของคลาสใด ๆ โดยใช้แผนที่ของข้อความ ตามแบบแผน ได้เมื่อสิ้นสุดการประกาศคลาส ตัวอย่างเช่น:

คลา CMyWnd: CMyParentWndClass สาธารณะ
{
 nbsp  / / สิ่งของฉัน...

ได้รับการป้องกัน:
    //{{AFX_MSG(CMyWnd)
    afx_msg โมฆะ OnPaint()
    //}}AFX_MSG

DECLARE_MESSAGE_MAP()
}(&N)

นี่คือรูปแบบสร้างขึ้น โดย AppWizard และ ClassWizard เมื่อต้องสร้างประเภทใหม่ / / { { และ / / } } วงเล็บจำเป็นสำหรับ ClassWizard?

มีกำหนดตารางการแมปข้อความ ด้วยชุดของแมโครที่ขยายแผนผังรายการของข้อความ ตารางเริ่มต้น ด้วยการBEGIN_MESSAGE_MAPแมโครโทร ซึ่งกำหนดชั้นที่ถูกจัดการ โดยการแมปข้อความนี้และชั้นหลักไม่ได้ข้อความจะถูกส่งผ่าน ตารางลงท้าย ด้วยการเรียกแมโคEND_MESSAGE_MAP?

ระหว่างการเรียกใช้แมโครทั้งสองเหล่านี้เป็นรายการสำหรับแต่ละข้อความจะจัดการ ด้วยการแมปข้อความนี้ ทุกข้อความ Windows มาตรฐานมีแมโครของฟอร์ม ON_WM_xxx (ที่ xxx คือ ชื่อของข้อความ) ที่สร้างรายการสำหรับข้อความ?

ได้มีกำหนดลายเซ็นของฟังก์ชันมาตรฐานสำหรับพารามิเตอร์ของแต่ละข้อความของ Windows ที่กำลังขยายข้อมูล และให้ความปลอดภัยชนิด อาจพบลายเซ็นเหล่านี้ในไฟล์ AFXWINในปฏิญญาสากลว่าด้วย CWnd H แต่ละตัวถูกทำเครื่องหมายด้วยคำafx_msgสำหรับรหัสที่ง่าย?

หมายเหตุnbsp  ClassWizard ต้องการให้คุณใช้คำสำคัญafx_msgในแผนที่ของคุณข้อความประกาศตัวจัดการ(&N)?

ลายเซ็นของฟังก์ชันเหล่านี้ขึ้นมาใช้แบบแผนการอย่างง่าย ชื่อของฟังก์ชันเริ่มต้น ด้วย "On" เสมอ นี้จะตาม ด้วยชื่อของข้อความ Windows กับ WM_ ถูกเอาออก และเฉพาะอักษรตัวแรกของแต่ละคำตัวพิมพ์ใหญ่ การสั่งซื้อของพารามิเตอร์เป็น wParam ตามด้วยLOWORD (lParam)แล้วHIWORD(lParam) พารามิเตอร์ที่ไม่ได้ใช้จะถูกส่งผ่านไม่ จับใด ๆ ที่ถูกห่อ ด้วยคลาสของ MFC จะถูกแปลงเป็นตัวชี้ไปยังวัตถุ MFC ที่เหมาะสม ตัวอย่างต่อไปนี้แสดงวิธีการจัดการกับข้อความWM_PAINTและทำให้เกิดการ CMyWnd:: OnPaintฟังก์ชันจะเรียก

BEGIN_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
 nbsp  //{{AFX_MSG_MAP(CMyWnd)
    ON_WM_PAINT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()(&N)

ต้องมีกำหนดตารางการแมปข้อความอยู่ภายนอกขอบเขตของคำจำกัดความที่ฟังก์ชันหรือคลาส มันควรไม่อยู่ภายในบล็อกการ "C" extern?

หมายเหตุnbsp  ClassWizard จะแก้ไขรายการการแมปข้อความที่พบระหว่างการ / / { { และ / / } } วงเล็บของข้อคิดเห็น(&N)?

ผู้ใช้กำหนดข้อความของ Windows

ข้อความที่ผู้ใช้กำหนดเองอาจถูกรวมไว้ในการแมปข้อความ โดยใช้แมโคON_MESSAGE แมโครนี้ยอมรับหมายเลขข้อความและฟังก์ชันสมาชิกของแบบฟอร์ม:

nbsp   / / ภาย ในการประกาศคลาส
    afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam)

ตัวอย่าง:
    #กำหนด WM_MYMESSAGE (WM_USER + 100)

BEGIN_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
    ON_MESSAGE (WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()(&N)

ในตัวอย่างนี้ เราสร้างตัวจัดการสำหรับข้อความแบบกำหนดเองที่ มี ID ข้อความ Windows ได้มาจากการมาตรฐานWM_USERพื้นฐานสำหรับข้อความที่ผู้ใช้กำหนด คุณอาจเรียกใช้ตัวจัดการนี้ ด้วยรหัสเช่น:

CWnd * pWnd =...;
pWnd-gtSendMessage(WM_MYMESSAGE)(&G)

ช่วงของข้อความที่ผู้ใช้กำหนดเองโดยใช้วิธีการนี้ต้องอยู่ในช่วง WM_USER ไป 0x7fff?

หมายเหตุnbsp  ClassWizard สนับสนุนงานประจำตัวจัดการON_MESSAGEใส่จากอินเทอร์เฟซสำหรับผู้ใช้ ClassWizard: คุณต้องป้อนด้วยตนเองเหล่านั้นจากตัวแก้ไข Visual c ++ เมื่อป้อน ClassWizard จะแยกวิเคราะห์ข้อมูลเหล่านี้ และช่วยให้คุณสามารถเรียกดูได้เช่นเดียวกับข้อความแผนผังรายการอื่น ๆ(&N)?

ลงทะเบียน Windows ข้อความ

การ:: RegisterWindowMessageฟังก์ชันใช้ในการกำหนดหน้าต่างข้อความใหม่ที่เป็นรับประกันจะไม่ซ้ำกันตลอดทั้งระบบ แมโคON_REGISTERED_MESSAGEใช้ในการจัดการกับข้อความเหล่านี้ แมโครนี้ยอมรับมีชื่อของตัวแปร UINT ใกล้ที่ประกอบด้วยหน้าต่างการลงทะเบียนข้อความรหัส ตัวอย่างเช่น

คลา CMyWnd: CMyParentWndClass สาธารณะ
{
สาธารณะ:
 nbsp  CMyWnd()

//{{AFX_MSG(CMyWnd)
    afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam)
    //}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

คง UINT ใกล้ WM_FIND = RegisterWindowMessage("COMMDLG_FIND")

BEGIN_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
    //{{AFX_MSG_MAP(CMyWnd)
    ON_REGISTERED_MESSAGE (WM_FIND, OnFind)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()(&N)

การลงทะเบียน Windows ข้อ ID แปร (WM_FIND ในตัวอย่างข้างต้น) ต้องเป็นตัวแปรที่ใกล้เนื่องจากวิธีการมีการใช้งานON_REGISTERED_MESSAGE?

ช่วงของข้อความที่ผู้ใช้กำหนดเองโดยใช้วิธีการนี้จะอยู่ในช่วง 0xC000 ไป 0xFFFF?

หมายเหตุnbsp  ClassWizard สนับสนุนงานประจำตัวจัดการON_REGISTERED_MESSAGEใส่จากอินเทอร์เฟซสำหรับผู้ใช้ ClassWizard คุณต้องป้อนด้วยตนเองเหล่านั้นจากตัวแก้ไขข้อความ เมื่อป้อน ClassWizard จะแยกวิเคราะห์ข้อมูลเหล่านี้ และช่วยให้คุณสามารถเรียกดูได้เช่นเดียวกับข้อความแผนผังรายการอื่น ๆ(&N)?

ข้อความคำสั่ง

ข้อความคำสั่งจากเมนูและ accelerators ได้รับการจัดการในการแมปข้อความกับแมโคON_COMMAND แมโครนี้ยอมรับเป็น ID คำสั่งรวมทั้งฟังก์ชันสมาชิก เพียงเฉพาะWM_COMMANDข้อความด้วยการwParamเท่ากับคำสั่งที่ระบุ ID ถูกจัดการ โดยฟังก์ชันสมาชิกระบุไว้ในรายการข้อความแผนที่ คำสั่งจัดการสมาชิกฟังก์ชันใช้ไม่มีพารามิเตอร์ และกลับโมฆะ แมโครที่มีฟอร์ม:

 ON_COMMAND (รหัส memberFxn)

ข้อความปรับปรุงคำสั่งถูกส่งผ่านมาทางกลไกเดียวกันเป็นตัวจัดการON_COMMAND แมโคON_UPDATE_COMMAND_UIถูกใช้แทน ปรับปรุงคำสั่งจัดการสมาชิกฟังก์ชันใช้พารามิเตอร์เดียว ตัวชี้ไปยังวัตถุCCmdUIและกลับโมฆะ แมโครที่มีฟอร์ม

ON_UPDATE_COMMAND_UI (รหัส memberFxn)

ฟอร์มที่มีส่วนขยายของตัวจัดการข้อความคำสั่งจะพร้อมใช้งานสำหรับการใช้งานขั้นสูง แมโคON_COMMAND_EXถูกใช้แทน และแสดงเซ็ตของหน้าที่การใช้งานON_COMMAND ฟังก์ชันเพิ่มเติมคำสั่งจัดการสมาชิกใช้พารามิเตอร์เดียว UINT ประกอบด้วยคำสั่ง ID และกลับเป็น BOOL กลับ BOOL ควรจริงเป็นการบ่งชี้ว่า คำสั่งที่ได้รับการจัดการ สายงานมิฉะนั้น จะยังวัตถุเป้าหมายของคำสั่ง?

ตัวอย่างของฟอร์มข้างต้น:

นอกจากนี้ใช้สำหรับการใช้งานขั้นสูงคือON_COMMAND_RANGEและON_COMMAND_RANGE_EXซึ่งช่วยให้คุณสามารถจัดการกับช่วงของคำสั่ง ด้วยตัวจัดการคำสั่งเดียว ดูเอกสารของผลิตภัณฑ์สำหรับข้อมูลเพิ่มเติมบนแมโครเหล่านี้?

หมายเหตุnbsp  ClassWizard สนับสนุนการสร้างON_COMMANDและON_UPDATE_COMMAND_UIตัวจัดการ แต่ไม่สนับสนุนตัวจัดการON_COMMAND_EXหรือON_COMMAND_RANGEที่สร้างขึ้น อย่างไรก็ตาม คลาสตัวช่วยสร้างจะแยกวิเคราะห์ และอนุญาตให้คุณเรียกดูตัวแปรตัวจัดการสามคำสั่งทั้งหมด(&N)?

ข้อความแจ้งเตือนของตัวควบคุม

รายการแมปข้อความที่ส่งจากตัวควบคุมลูกไปยังหน้าต่าง มีเตียงบิตของข้อมูลในข้อความ: รหัสของตัวควบคุม ตัวจัดการข้อความที่ระบุในรายการการแมปข้อความเรียกว่าเฉพาะถ้าแจ้ง (1)รหัสควบคุม (สูงคำ lParam), เช่น BN_CLICKED ตรงกับรหัสการแจ้งเตือนระบุไว้ในรายการข้อความแผนที่ และ (2) ตัวควบคุม ID (wParam) ตรงกับรหัสควบคุมที่ระบุในรายการข้อความแผนที่?

ข้อความแจ้งเตือนของตัวควบคุมแบบกำหนดเองอาจใช้แมโคON_CONTROLเพื่อกำหนดรายการแผนที่ข้อความ ด้วยรหัสการแจ้งเตือนแบบกำหนดเอง แมโครนี้มีแบบฟอร์ม

ON_CONTROL (wNotificationCode หมายเลข memberFxn)

สำหรับการใช้งานขั้นสูงON_CONTROL_RANGEสามารถใช้เพื่อจัดการการแจ้งเตือนเฉพาะควบคุมจากช่วงของการควบคุม ด้วยตัวจัดการเดียวกัน?

ClassWizard สนับสนุนการสร้างตัวจัดการที่ON_CONTROLหรือON_CONTROL_RANGEในส่วนติดต่อผู้ใช้ คุณต้องป้อนด้วยตนเองได้กับตัวแก้ไขข้อความ เมื่อป้อน ClassWizard จะแยกวิเคราะห์ข้อมูลเหล่านี้ และช่วยให้คุณสามารถเรียกดูได้เช่นเดียวกับอื่น ๆ ข้อความแผนผังรายการใด ๆ?

ตัวควบคุมทั่วไปของ Windows ให้มีประสิทธิภาพสูงWM_NOTIFYใช้สำหรับการแจ้งเตือนของตัวควบคุมที่ซับซ้อน MFC รุ่นนี้มีการสนับสนุนสำหรับข้อความนี้ใหม่กับแมโคON_NOTIFYและON_NOTIFY_RANGEโดยตรง ดูเอกสารของผลิตภัณฑ์สำหรับข้อมูลเพิ่มเติมบนแมโครเหล่านี้?

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

Index