หมายเหตุทางเทคนิคนี้ให้ข้อมูลเบื้องหลังเกี่ยวกับWM_NOTIFYข้อความใหม่ และอธิบายวิธีแนะนำ (และทั่วไป) ของการจัดการข้อความWM_NOTIFYในโปรแกรมประยุกต์ของคุณ MFC?
ข้อความแจ้งเตือนใน Windows 3.x
ใน Windows 3.x ควบคุมแจ้งพ่อของเหตุการณ์ต่าง ๆ เช่นการคลิกเมาส์ ในการเปลี่ยนแปลงเนื้อหา และเลือก และระบายสีพื้นหลังของตัวควบคุม โดยการส่งข้อความไปแม่ วิแจ้งเตือนจะถูกส่งเป็นข้อพิเศษWM_COMMANDความ ที่มีรหัสการแจ้งเตือน (เช่นBN_CLICKED) และควบคุม ID ที่บรรจุลงในwParamและหมายเลขอ้างอิงของตัวควบคุมในlParam โปรดสังเกตว่า เนื่องจากwParamและlParamมีทั้งหมด ไม่มีวิธีการส่งผ่านข้อมูลใด ๆ เพิ่มเติม ข้อความเหล่านี้สามารถแจ้งเตือนวิเท่านั้น ตัวอย่าง ในการแจ้งBN_CLICKEDไม่มีวิธีการส่งข้อมูลเกี่ยวกับตำแหน่งที่ตั้งของเคอร์เซอร์ของเมาส์เมื่อปุ่มถูกคลิก?
เมื่อตัวควบคุมใน Windows 3.x จำเป็นต้องส่งข้อความแจ้งเตือนที่มีข้อมูลเพิ่มเติมผู้ใช้หลากหลายข้อความพิเศษวัตถุประสงค์ รวมทั้งWM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEMและอื่น ๆ ข้อความเหล่านี้สามารถถูกสะท้อนกลับไปตัวควบคุมที่ส่งไป ดูข้อมูลเพิ่มเติมTN062: ข้อความเงาสำหรับ Windows ตัวควบคุม?
สำหรับตัวควบคุมที่มีอยู่ใน Windows 3.1, API Win32 ใช้ส่วนใหญ่ของข้อความแจ้งเตือนที่ถูกใช้ใน Windows 3.x อย่างไรก็ตาม Win32 เพิ่มจำนวนของตัวควบคุมที่ซับซ้อน ซับซ้อนที่ได้รับการสนับสนุนใน Windows 3.x บ่อย ตัวควบคุมเหล่านี้จำเป็นต้องส่งข้อมูลเพิ่มเติม ด้วยข้อความแจ้งเตือนของตน แทนที่เพิ่มข้อแบบใหม่ WM_ ความสำหรับการแจ้งเตือนแต่ละใหม่ที่ต้องการข้อมูลเพิ่มเติมนักออกแบบของ API Win32 เลือกเมื่อต้องการเพิ่มข้อความเพียงหนึ่งWM_NOTIFYซึ่งสามารถส่งผ่านข้อมูลเพิ่มเติมจำนวนใด ๆ ในมาตรฐาน?
ข้อความที่WM_NOTIFYมี ID ของตัวควบคุมที่ส่งข้อความในwParamและตัวชี้ไปยังโครงสร้างในlParam โครงสร้างนี้เป็นโครงสร้างแบบNMHDRหรือบางโครงสร้างขนาดใหญ่ที่มีโครงสร้างแบบNMHDRเป็นสมาชิกแรก โปรดสังเกตว่า เนื่องจากสมาชิกNMHDRเป็นครั้งแรก สามารถใช้เป็นตัวชี้ไปยังโครงสร้างนี้เป็นการชี้ไปNMHDRหรือเป็นตัวชี้ไปยังโครงสร้างใหญ่ขึ้นอยู่กับว่า คุณทอดนั้น?
ในกรณีส่วนใหญ่ ตัวชี้จะชี้ไปที่โครงสร้างใหญ่กว่า และคุณจำเป็นต้องทอดเมื่อคุณใช้ เพียงไม่กี่แจ้ง เช่นการแจ้งเตือนทั่วไป (ชื่อขึ้นต้นด้วยNM_) และเครื่องมือเคล็ดลับของตัวควบคุมTTN_SHOWและแจ้ง เตือนTTN_POPเป็นโครงสร้างแบบNMHDRที่ใช้จริง?
โครงสร้างของNMHDRหรือสมาชิกเริ่มแรกประกอบด้วยหมายเลขอ้างอิงและ ID ของตัวควบคุมที่ส่งข้อความและรหัสการแจ้งเตือน (เช่นTTN_SHOW) รูปแบบของโครงสร้างNMHDRจะแสดงอยู่ด้านล่าง:
typedef struct tagNMHDR {
nbsp HWND hwndFrom
UINT idFrom
รหัส UINT
} NMHDR(&N)
สำหรับข้อความTTN_SHOW รหัสสมาชิกต้องถูกตั้งค่าเป็นTTN_SHOW?
การแจ้งเตือนส่วนใหญ่ผ่านตัวชี้ไปยังโครงสร้างขนาดใหญ่ที่ประกอบด้วยโครงสร้างแบบNMHDRเป็นสมาชิกแรก ตัวอย่าง พิจารณาโครงสร้างที่ใช้ โดยรายการมุมมองของตัวควบคุมLVN_KEYDOWNข้อแจ้งเตือน ซึ่งจะถูกส่งไปเมื่อมีกดแป้นในตัวควบคุมมุมมองรายการ ชี้จุดโครงLV_KEYDOWNสร้าง ซึ่งกำหนดไว้ดังแสดงด้านล่าง:
typedef struct tagLV_KEYDOWN {
nbsp NMHDR hdr
WORD wVKey
ค่าสถานะ UINT
} LV_KEYDOWN(&N)
โปรดสังเกตว่า เนื่องจากสมาชิกNMHDRเป็นครั้งแรกในโครงสร้างนี้ ตัวชี้ที่คุณกำลังส่งผ่านข้อความแจ้งเตือนสามารถจะทอดตัวชี้ไปNMHDRหรือตัวชี้ไปLV_KEYDOWN?
แจ้งทั่วไปในการควบคุมของ Windows ใหม่ทั้งหมด
แจ้งเตือนบางทั่วไปทั้งหมดของตัวควบคุมใหม่ของ Windows ได้ การแจ้งเตือนเหล่านี้ผ่านตัวชี้การโครงสร้างNMHDR?
| รหัสการแจ้งเตือน | ส่งได้เนื่องจาก |
| NM_CLICK | ผู้ใช้คลิกปุ่มเมาส์ทางซ้ายในตัวควบคุม |
| NM_DBLCLK | ปุ่มเมาส์ข้างซ้าย double-clicked ผู้ใช้ในตัวควบคุม |
| NM_RCLICK | ผู้ใช้คลิกปุ่มเมาส์ขวาในตัวควบคุม |
| NM_RDBLCLK | ปุ่มเมาส์ขวา double-clicked ผู้ใช้ในตัวควบคุม |
| NM_RETURN | ผู้ใช้กดปุ่ม ENTER ในขณะที่ควบคุมได้ป้อนการโฟกัส |
| NM_SETFOCUS | ควบคุมได้รับโฟกัสที่ป้อนข้อมูล |
| NM_KILLFOCUS | ควบคุมได้หายโฟกัสที่ป้อนข้อมูล |
| NM_OUTOFMEMORY | ตัวควบคุมไม่สามารถเสร็จสมบูรณ์การดำเนินการเนื่องจากไม่มีเงินเพียงพอที่จะใช้หน่วยความจำได้ |
ON_NOTIFY: การจัดการข้อความ WM_NOTIFY ในโปรแกรมประยุกต์ของ MFC
ฟังก์ชันCWnd::OnNotifyจัดการกับข้อความแจ้งเตือน เริ่มต้นใช้งานการตรวจสอบการแมปข้อความสำหรับตัวจัดการการแจ้งเตือนการโทร ทั่วไป คุณไม่แทนOnNotify แทน คุณให้ฟังก์ชันตัวจัดการ และเพิ่มการแมปข้อความสำหรับตัวจัดการที่การแมปข้อความของคลาสหน้าต่างเจ้าของของคุณ?
ClassWizard ผ่านแผ่นคุณสมบัติ ClassWizard หรือ WizardBar สามารถสร้างรายการข้อความแผนที่ON_NOTIFYและให้คุณ มีฟังก์ชันตัวจัดการโครงกระดูก ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ ClassWizard เพื่อทำได้ง่ายขึ้น การแมปข้อความไปยังฟังก์ชันในรายการแนะนำของ Visual c ++ Programmer ของ?
แมโคON_NOTIFYข้อความแผนที่มีไวยากรณ์ดังต่อไปนี้:
ON_NOTIFY ( wNotifyCode, รหัส, memberFxn )
ที่ italicized พารามิเตอร์จะถูกแทนที่ด้วย:
wNotifyCode
รหัสสำหรับข้อความแจ้งเตือนที่จะจัดการ เช่นLVN_KEYDOWN?
รหัส
ตัวระบุเด็กของตัวควบคุมที่มีส่งการแจ้งเตือน?
memberFxn
สมาชิกฟังก์ชันถูกเรียกว่าเมื่อมีส่งการแจ้งเตือนนี้?
ฟังก์ชันของสมาชิกที่ต้องประกาศกับตัวแบบตัวอย่างต่อไปนี้:
afx_msg โมฆะ memberFxn( NMHDR * pNotifyStruct, LRESULT * ผล );
พารามิเตอร์ italicized อยู่ที่ไหน:
pNotifyStruct
ตัวชี้การโครงสร้างการแจ้งเตือน ตามที่อธิบายไว้ในส่วนข้างต้น?
ผลลัพธ์
ตัวชี้ไปยังรหัสผลคุณสามารถกำหนดก่อนที่คุณส่งคืน?
ตัวอย่าง
เมื่อต้องการระบุว่า คุณต้องการให้ฟังก์ชันสมาชิก OnKeydownList1 การจัดการข้อความLVN_KEYDOWNจากCListCtrlที่มี ID คือ IDC_LIST1 คุณต้องใช้ ClassWizard เพื่อเพิ่มต่อไปนี้ในการแมปข้อความของคุณ:
ON_NOTIFY (LVN_KEYDOWN, IDC_LIST1, OnKeydownList1)
ในตัวอย่างข้างต้น คือฟังก์ชันโดย ClassWizard:
โมฆะ CMessageReflectionDlg::OnKeydownList1 (pNMHDR NMHDR * LRESULT * pResult)
{
LV_KEYDOWN * pLVKeyDow = (LV_KEYDOWN *) pNMHDR
/ / TODO: เพิ่มตัวจัดการการแจ้งเตือนของคุณควบคุม
/ / nbsp รหัสต่อไปนี้
* pResult = 0
}(&N)
หมายเหตุว่า ClassWizard แสดงตัวชี้ของชนิดเหมาะสมโดยอัตโนมัติ คุณสามารถเข้าถึงโครงสร้างการแจ้งเตือนผ่านทางใด pNMHDR หรือpLVKeyDow?
ถ้าคุณต้องการประมวลผลข้อความWM_NOTIFYเดียวสำหรับชุดของตัวควบคุม คุณสามารถใช้ON_NOTIFY_RANGEแทนที่เป็นON_NOTIFY ตัวอย่างเช่น คุณอาจมีชุดของปุ่มที่คุณต้องการทำการกระทำเดียวกันบางข้อความแจ้งเตือน?
เมื่อคุณใช้ON_NOTIFY_RANGEคุณระบุช่วงของตัวระบุเด็กซึ่งการจัดการข้อความแจ้งเตือน โดยการระบุจุดเริ่มต้น และสิ้นสุดการตัวระบุเด็กช่วงต่อเนื่อง?
ClassWizard ไม่ได้จัดการON_NOTIFY_RANGE การใช้งาน คุณจำเป็นต้องแก้ไขการแมปข้อความของคุณด้วยตัวคุณเอง?
การแมปข้อความและฟังก์ชันต้นสำหรับON_NOTIFY_RANGEมีดังนี้:
ON_NOTIFY_RANGE ( wNotifyCode, รหัส, idLast, memberFxn )
ที่ italicized พารามิเตอร์จะถูกแทนที่ด้วย:
wNotifyCode
รหัสสำหรับข้อความแจ้งเตือนที่จะจัดการ เช่นLVN_KEYDOWN?
รหัส
ตัวระบุแรกในช่วงของตัวระบุที่อยู่ติดกัน?
idLast
ตัวระบุที่สุดท้ายในช่วงต่อเนื่องของตัวระบุ?
memberFxn
สมาชิกฟังก์ชันถูกเรียกว่าเมื่อมีส่งการแจ้งเตือนนี้?
ฟังก์ชันของสมาชิกที่ต้องประกาศกับตัวแบบตัวอย่างต่อไปนี้:
afx_msg โมฆะ memberFxn( UINTรหัส, NMHDR * pNotifyStruct, LRESULT * ผล );
พารามิเตอร์ italicized อยู่ที่ไหน:
รหัส
ตัวระบุเด็กของตัวควบคุมที่ส่งการแจ้งเตือน?
pNotifyStruct
ตัวชี้ไปยังโครงสร้างการแจ้งเตือน ตามที่อธิบายไว้ข้างต้น?
ผลลัพธ์
ตัวชี้ไปยังรหัสผลคุณสามารถกำหนดก่อนที่คุณส่งคืน?
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
ถ้าคุณต้องการให้วัตถุมากกว่าหนึ่งในสายงานการผลิตการจัดการข้อความแจ้งเตือน คุณสามารถใช้ON_NOTIFY_EX (หรือON_NOTIFY_EX_RANGE) แทนที่ON_NOTIFY (หรือON_NOTIFY_RANGE) ข้อแตกต่างระหว่างรุ่นอดีตและเวอร์ชันปกติเท่านั้นคือ ว่า ฟังก์ชันของสมาชิกที่เรียกว่าสำหรับรุ่นอดีตส่งกลับเป็นBOOLที่บ่งชี้ว่า การประมวลผลข้อความควรดำเนินการต่อไป ผิดพลาดส่งกลับจากฟังก์ชันนี้ช่วยให้คุณสามารถประมวลผลข้อความเดียวกันมากกว่าหนึ่งวัตถุ?
ไม่มีจัดการ ClassWizard ON_NOTIFY_EXหรือON_NOTIFY_EX_RANGE ถ้าคุณต้องการใช้อย่างใดอย่างหนึ่งเหล่านี้ คุณต้องแก้ไขการแมปข้อความของคุณด้วยตัวคุณเอง?
การแมปข้อความและฟังก์ชันต้นสำหรับON_NOTIFY_EXและON_NOTIFY_EX_RANGEมีดังนี้ ในความหมายของพารามิเตอร์จะเหมือนกับการไม่ใช่-รุ่นอดีต?
ON_NOTIFY_EX ( nCode, รหัส, memberFxn )
ON_NOTIFY_EX_RANGE ( wNotifyCode, รหัส, idLast,memberFxn )
แบบตัวอย่างการสำหรับทั้งสองด้านบนจะเหมือนกัน:
afx_msg BOOL memberFxn( UINTรหัส, NMHDR * pNotifyStruct, LRESULT * ผล );
ในทั้งสองกรณีหมายเลขเก็บตัวระบุเด็กของตัวควบคุมที่ส่งการแจ้งเตือน?
ฟังก์ชันของคุณต้องการส่งกลับTRUEถ้าข้อความแจ้งเตือนได้ถูกจัดการอย่างสมบูรณ์ หรือเป็น FALSEถ้าอื่น ๆ วัตถุในสายงานการสั่งควรมีโอกาสที่จะจัดการข้อความ?
หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)