หมายเหตุนี้อธิบายถึงการอำนวยการแมปข้อความของ 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 ควรจริงเป็นการบ่งชี้ว่า คำสั่งที่ได้รับการจัดการ สายงานมิฉะนั้น จะยังวัตถุเป้าหมายของคำสั่ง?
ตัวอย่างของฟอร์มข้างต้น:
#definenbsp ID_MYCMD 100
#กำหนด ID_COMPLEX 101(&N)
afx_msg โมฆะ OnMyCommand()
afx_msg โมฆะ OnUpdateMyCommand (CCmdUI * pCmdUI);
afx_msg BOOL OnComplexCommand(UINT nID)
ON_COMMAND (ID_MYCMD, OnMyCommand)
ON_UPDATE_COMMAND_UI (ID_MYCMD, OnUpdateMyCommand)
ON_COMMAND_EX (ID_MYCMD, OnComplexCommand)
โมฆะ CMyClass::OnMyCommand()
{
nbsp / / จัดการคำสั่ง
}
โมฆะ CMyClass::OnUpdateMyCommand (CCmdUI * pCmdUI)
{
/ / ตั้งค่าสถานะ UI กับ pCmdUI
}
BOOL CMyClass::OnComplexCommand(UINT nID)
{
/ / จัดการคำสั่ง
ส่งกลับ TRUE
}(&N)
นอกจากนี้ใช้สำหรับการใช้งานขั้นสูงคือ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)