หมายเหตุนี้อธิบายถึงการสถาปัตยกรรมของสายงานการผลิตและการส่งคำสั่งตลอดจนหัวข้อขั้นสูงในการกำหนดเส้นทางข้อความหน้าต่างทั่วไป?
โปรดดูคำแนะนำของ Visual c ++ Programmer ของสำหรับรายละเอียดทั่วไปเกี่ยวกับสถาปัตยกรรมอธิบายไว้ที่นี่ โดยเฉพาะแยกความแตกต่างในระหว่าง Windows ข้อ ควบคุม และการแจ้งเตือนคำสั่ง หมายเหตุนี้ถือว่า คุณมีความคุ้นเคยกับปัญหาอธิบายไว้ในเอกสารที่พิมพ์ออกมามาก และเน้นหัวข้อมากขั้นสูงเท่านั้น?
คำสั่งการกำหนดเส้นทางและการสรุปข้อมูล MFC 1.0 ฟังก์ชันการทำงานที่ค่อย ๆ เปลี่ยนไป MFC 2.0 สถาปัตยกรรม
Windows มีความWM_COMMANDที่มีเพียบเพื่อให้มีการแจ้งเตือนของคำสั่งเมนู เร่งความเร็วแป้น และควบคุมโต้ตอบแจ้งเตือน?
MFC 1.0 ที่มีอยู่แล้วภายในที่เพียงเล็กน้อย โดยการอนุญาตให้ตัวคำสั่งจัดการ (ตัวอย่างเช่น, "OnFileNew") ในการCWndมายังได้รับการตอบสนองต่อการระบุWM_COMMANDเรียกคลา นี้จะจมปลักกับโครงสร้างข้อมูลเรียกว่าแผนที่ความ และผลลัพธ์ในกลไกการคำสั่งที่มีช่องว่างประสิทธิภาพ?
MFC 1.0 ให้ใช้ฟังก์ชันเพิ่มเติมสำหรับการแบ่งตัวควบคุมแจ้งจากข้อความคำสั่งเช่นกัน คำสั่งจะแสดง ด้วย ID 16 bit บางครั้งเรียกว่าคำสั่งรหัส โดยปกติคำสั่งเริ่มต้นจากการCFrameWnd (เช่น: การเลือกเมนูหรือเร่งการแปล) และได้รับการกำหนดเส้นทางไปยังหน้าต่างอื่น?
MFC 1.0 ใช้คำสั่งกำหนดเส้นทางในความรู้สึกที่จำกัดสำหรับการใช้งานของหลายเอกสาร Interface (MDI) (หน้าต่างเฟรม MDI มอบคำสั่งสำหรับหน้าต่าง MDI เด็กของใช้งานอยู่)
ฟังก์ชันการทำงานนี้ถูก generalized และขยายใน MFC 2.0 เพื่อให้คำสั่งที่จะจัดการ โดยช่วงกว้างของวัตถุ (ไม่ใช่แค่หน้าต่างวัตถุ) และมีการเพิ่มเติมและเป็นทาง และสถาปัตยกรรมแบบขยายได้สำหรับการกำหนดเส้นทางข้อความ และ reuses สายคำสั่งเป้าหมายงานการ การจัดการไม่เพียง คำสั่ง แต่ยัง สำหรับการปรับปรุงวัตถุ UI (เช่นรายการเมนูและปุ่มแถบเครื่องมือ) เพื่อสะท้อนความพร้อมคำสั่งในปัจจุบัน?
รหัสคำสั่ง
ดูที่คู่มือ Visual c ++ Programmer ของคำอธิบายของคำสั่งที่กำหนดเส้นทาง และกระบวนการการผูก 20 หมายเหตุทางเทคนิคประกอบด้วยข้อมูลเกี่ยวกับการตั้งชื่อ ID?
เราใช้คำนำหน้าทั่วไป "ID_" สำหรับรหัสคำสั่ง คำสั่งรหัสจะ gt = 0x8000 แถบสถานะหรือเส้นข้อความจะแสดงสตริงที่อธิบายคำสั่งว่า มีทรัพยากร STRINGTABLE กับรหัสเดียวกันเป็นคำสั่ง ID(&G)?
ในแหล่งข้อมูลของโปรแกรมประยุกต์ของคุณ คำสั่ง ID สามารถปรากฏในหลายแห่ง:
ในโค้ดต้นฉบับของโปรแกรมประยุกต์ของคุณ คำสั่ง ID สามารถปรากฏในหลายแห่ง:
ในปัจจุบัน การใช้งานเฉพาะใน MFC ที่ต้องใช้รหัสคำสั่งจะ gt; = 0x8000 เป็นการใช้งาน GOSUB กล่องโต้ตอบแสดง/คำสั่ง(&G)?
คำสั่ง GOSUB ใช้สถาปัตยกรรมของคำสั่งในกล่องโต้ตอบ
สถาปัตยกรรมของสายงานการผลิต และการเปิดใช้งานคำสั่งคำสั่งทำงานได้ดีกับกรอบ windows รายการเมนู ปุ่มแถบเครื่องมือ โต้ตอบแถบปุ่ม แถบควบคุมอื่น ๆ และองค์ประกอบของส่วนติดต่อผู้ใช้อื่น ๆ ออกแบบมาเพื่อปรับปรุงในคำสั่งต่าง ๆ ที่ความต้องการและกระบวนการผลิต หรือควบคุมรหัสคำสั่งหลักเป้าหมาย (โดยปกติแล้วหน้าต่างเฟรมหลัก) กระบวนการเป้าหมายที่คำสั่งหลักอาจผลิตแจ้งการสั่งหรือตัวควบคุมวัตถุเป้าหมายของคำสั่งอื่น ๆ ตามความเหมาะสม?
กล่องโต้ตอบ (โมดอล หรือสร้าง) จะได้ประโยชน์จากคุณลักษณะของสถาปัตยกรรมคำสั่งบางอย่างถ้าคุณกำหนด ID ตัวควบคุมของตัวควบคุมการโต้ตอบรหัสคำสั่งที่เหมาะสม การสนับสนุนสำหรับกล่องโต้ตอบไม่อัตโนมัติ ดังนั้นคุณอาจต้องเขียนโค้ดบางอย่างเพิ่มเติม?
หมายเหตุว่า สำหรับทุกคุณลักษณะเหล่านี้ในการทำงานอย่างถูกต้อง รหัสคำสั่งของคุณควร gt = 0x8000 คำสั่งที่ใช้งานร่วมกันเนื่องจากไม่สามารถรับส่งกล่องโต้ตอบหลายเฟรมเดียวกัน ควร > = 0x8000 ในขณะไม่ได้ใช้ร่วมกัน IDC ของในกล่องโต้ตอบเฉพาะควร < = 0x7FFF?
คุณสามารถทำปุ่มปกติในกล่องโต้ตอบโมดอลปกติกับ IDC ของปุ่มตั้งค่ารหัสการสั่งที่เหมาะสม เมื่อผู้ใช้เลือกปุ่ม เจ้าของกล่องโต้ตอบ (โดยปกติแล้วหน้าต่างเฟรมหลัก) ได้รับคำสั่งเช่นเดียวกับคำสั่งใด ๆ นี้เรียกว่าคำสั่ง GOSUB เนื่องจากโดยปกติแล้วการใช้ชุบเลี้ยงการโต้ตอบอื่น (GOSUB ของกล่องโต้ตอบแรก)?
นอกจากนี้คุณยังสามารถเรียกใช้ฟังก์ชันCWnd::UpdateDialogControlsในการโต้ตอบของคุณ และส่งอยู่ของหน้าต่างเฟรมหลักของคุณ นี้ฟังก์ชันจะเปิดใช้งานหรือปิดใช้งานตัวควบคุมการโต้ตอบของคุณยึดว่ามีตัวจัดการคำสั่งในเฟรม ฟังก์ชันนี้จะเรียกโดยอัตโนมัติให้คุณสำหรับแถบควบคุมการวนซ้ำไม่ได้ใช้งานของโปรแกรมประยุกต์ของคุณ แต่คุณต้องเรียกโดยตรงสำหรับกล่องโต้ตอบปกติที่คุณต้องการมีคุณลักษณะนี้?
เมื่อมีเรียก ON_UPDATE_COMMAND_UI
การรักษาสถานะการเปิดใช้งาน/การตรวจสอบรายการเมนูทั้งหมดของโปรแกรมตลอดเวลาได้มีปัญหา computationally แพง เทคนิคทั่วไปคือการ เปิดใช้งาน/เช็ครายการเมนูเฉพาะเมื่อผู้ใช้เลือกเมนูผุดขึ้น ใช้งาน MFC 2.0 CFrameWndจับความWM_INITMENUPOPUPและใช้คำสั่งสายงานสถาปัตยกรรมเพื่อตรวจสอบสถานะของเมนูผ่านตัวจัดการON_UPDATE_COMMAND_UI?
นอกจากนี้CFrameWndยังจับWM_ENTERIDLEข้อความเพื่ออธิบายเมนูการปัจจุบันสินค้าที่เลือกบนแถบ (เรียกอีกอย่างว่าบรรทัดข้อความ) สถานะ?
โครงสร้างเมนูของโปรแกรมประยุกต์ แก้ไข โดย Visual c ++ จะใช้เพื่อแสดงคำสั่งอาจเกิดขึ้นได้เวลาWM_INITMENUPOPUP ตัวจัดการON_UPDATE_COMMAND_UIสามารถปรับเปลี่ยนสถานะหรือข้อความของเมนู หรือสำหรับการใช้งานขั้นสูง (เช่นรายการแฟ้ม MRU หรือ OLE กริยาเมนูแบบผุดขึ้น), จริง ๆ แล้วแก้ไขโครงสร้างเมนูก่อนมีลากเมนู?
การเรียงลำดับของการประมวลผลON_UPDATE_COMMAND_UIเดียวกันเสร็จเรียบร้อยสำหรับแถบเครื่องมือ (และแถบควบคุมอื่น ๆ) เมื่อโปรแกรมประยุกต์ป้อนการวนรอบที่ไม่ได้ใช้งาน ดูข้อมูลอ้างอิงไลบรารีของคลาสและเทคนิคหมายเหตุ 31สำหรับข้อมูลเพิ่มเติมเกี่ยวกับแถบควบคุม?
เมนูแบบผุดขึ้นที่ซ้อนกัน
ถ้าคุณกำลังใช้โครงสร้างซ้อนกันเมนู คุณจะสังเกตเห็นว่า ตัวจัดการON_UPDATE_COMMAND_UIสำหรับรายการเมนูแรกในแบบผุดขึ้นเรียกว่าในสองกรณีที่แตกต่างกัน?
ครั้งแรก นั้นถูกเรียกสำหรับการผุดขึ้นเอง นี้เป็นสิ่งจำเป็นเนื่องจากเมนูแบบผุดขึ้นไม่มีรหัส และเราใช้ ID ของรายการเมนูแรกของเมนูผุดขึ้นเพื่ออ้างอิงถึงเมนูผุดขึ้นทั้งหมด ในกรณีนี้กำหนดให้ตัวแปรm_pSubMenuสมาชิกของวัตถุCCmdUIจะไม่เป็นค่า NULL และจะชี้ไปที่เมนูแบบผุดขึ้น?
ประการที่สอง โดยเรียกว่าก่อนจะวาดรายการในเมนูในเมนูผุดขึ้น ในกรณีนี้ ID ที่มีการอ้างอิงถึงรายการเมนูแรกเพียง และตัวแปรสมาชิกของm_pSubMenuของวัตถุCCmdUIจะเป็น NULL?
นี้ช่วยให้คุณสามารถเปิดการใช้งานแตกต่างจากไอเท็มของเมนูแบบผุดขึ้น แต่ต้องการให้คุณจดรหัสการทราบบางเมนู ในเมนูซ้อนกันที่มีโครงสร้างดังตัวอย่าง:
Filegt
ใหม่ >
แผ่น (ID_NEW_SHEET)
แผนภูมิ (ID_NEW_CHART)
คำสั่ง ID_NEW_SHEET และ ID_NEW_CHART สามารถแยกเปิดใช้งาน หรือปิดใช้งาน เมนูแบบผุดขึ้น "New" ควรจะเปิดการใช้งานถ้าอย่างใดอย่างหนึ่งทั้งสองถูกเปิดใช้งาน?
ตัวจัดการคำสั่งสำหรับ ID_NEW_SHEET (คำสั่งแรกในแบบผุดขึ้น) จะมีลักษณะคล้าย:
โมฆะ CMyApp::OnUpdateNewSheet (CCmdUI * pCmdUI)
{
nbsp ถ้า (pCmdUI - > m_pSubMenu ! = NULL)
{
/ / เปิดการใช้งานแบบผุดขึ้นทั้งหมดสำหรับ "New" แผ่นงานและแผนภูมิ
BOOL bEnable = m_bCanCreateSheet || m_bCanCreateChart
/ / CCmdUI::Enable เป็น op แทนไม่ใช่คำสำหรับกรณีนี้ ดังนั้นเรา
/ / ต้องทำอะไรก็จะสามารถดำเนินการ
pCmdUI - > m_pMenu - > EnableMenuItem (pCmdUI - > m_nIndex
MF_BYPOSITION |
(bEnable MF_ENABLED: (MF_DISABLED | MF_GRAYED)));
กลับ
}
/ / มิฉะนั้น เพียงคำสั่งแผ่นงานใหม่
pCmdUI - > Enable(m_bCanCreateSheet)
}
ตัวจัดการคำสั่งสำหรับ ID_NEW_CHART เป็นตัวจัดการคำสั่งปรับปรุงปกติและมองหาสิ่งที่ต้องการ:
โมฆะ CMyApp::OnUpdateNewChart (CCmdUI * pCmdUI)
{
nbsp pCmdUI - > Enable(m_bCanCreateChart)
}
ON_COMMAND และ ON_BN_CLICKED
แมโครการแมปข้อความสำหรับON_COMMANDและON_BN_CLICKEDเหมือนกัน MFC ควบคุมและสั่งการแจ้งเตือนสายกลไกในการใช้คำสั่ง ID การตัดสินใจที่จะใช้กระบวนผลิตเท่านั้น แจ้งการควบคุม ด้วยรหัสการแจ้งเตือนการควบคุมของศูนย์ (BN_CLICKED) จะถูกแปลเป็นคำสั่ง?
หมายเหตุขั้นสูง: ในความเป็นจริงที่แท้จริง ข้อความแจ้งเตือนของตัวควบคุมทั้งหมดไปถึงลูกโซ่ตัวจัดการคำสั่ง ดังนั้น จึงเป็นไปได้เทคนิคการเขียนตัวจัดการการแจ้งเตือนการควบคุมสำหรับว่าที่EN_CHANGEในคลาสเอกสารของคุณ อันนี้ไม่ขอแนะนำโดยทั่วไปเนื่องจากแอปพลิเคชั่นที่เป็นประโยชน์ของคุณลักษณะนี้จะไม่กี่ คุณลักษณะไม่ได้รับการสนับสนุน โดย ClassWizard และใช้คุณลักษณะอาจทำให้รหัสที่กรอบ?
การปิดใช้งานการปิดใช้งานโดยอัตโนมัติของปุ่มควบคุม
ถ้าคุณทำตัวควบคุมปุ่ม บนแถบการโต้ตอบ หรือการโต้ตอบใช้ที่คุณกำลังเรียกCWnd::UpdateDialogControlsในของคุณเอง คุณจะสังเกตเห็นว่า ปุ่มซึ่งไม่มีตัวจัดการที่ON_COMMANDหรือON_UPDATE_COMMAND_UIจะถูกปิดโดยอัตโนมัติใช้สำหรับคุณ ด้วยกรอบ ในบางกรณี คุณจะไม่จำเป็นต้องมีตัวจัดการ แต่คุณจะต้องการให้ปุ่มยังคงเปิดใช้งาน วิธีที่ง่ายที่สุดเพื่อให้ได้นี้คือการ เพิ่มตัวจัดการคำสั่งที่ไม่มีตัวตน (ง่ายต่อการทำ ClassWizard) และไม่ต้องทำอะไรในนั้น?
การกำหนดเส้นทางข้อความหน้าต่าง
ต่อไปนี้อธิบายหัวข้อบางขั้นสูงเพิ่มเติมบนคลาสที่ MFC และวิธีการกำหนดเส้นทางข้อความ Windows และหัวข้ออื่น ๆ ลดเหล่านั้น ข้อมูลที่มีการอธิบายไว้เพียงสั้น ๆ อ้างถึงชั้นการอ้างอิงไลบรารีสำหรับรายละเอียดเกี่ยวกับสาธารณะ APIs โปรดไปที่ไลบรารีของ MFC รหัสแหล่งที่มาสำหรับข้อมูลเพิ่มเติมเกี่ยวกับรายละเอียดการใช้งาน?
กรุณาอ้างอิงถึง17 หมายเหตุทางเทคนิคสำหรับรายละเอียดเกี่ยวกับการล้างข้อมูลบนหน้าต่าง หัวข้อสำคัญมากสำหรับทั้งหมดCWnd-มาเรียน?
ปัญหา CWnd
ฟังก์ชันการใช้งานสมาชิกCWnd::OnChildNotifyมีสถาปัตยกรรมมีประสิทธิภาพ และสามารถขยายได้สำหรับเด็ก windows (หรือที่เรียกว่าตัวควบคุม) ตะขอ หรือมิฉะนั้น รับทราบข้อความ คำสั่ง และควบคุมการแจ้งเตือนที่ไปยังผู้ปกครอง (หรือ "เจ้าของ") ถ้าหน้าต่างลูก (/ ควบคุม) คือ วัตถุ c ++ CWndตัวเอง เสมือนฟังก์ชันOnChildNotifyจะเรียกว่าครั้งแรกกับพารามิเตอร์จากข้อความต้นฉบับ (นั่นคือ เป็นโครงสร้างMSG ) หน้าต่างลูกสามารถฝากข้อความคนเดียว กิน หรือปรับเปลี่ยนข้อความสำหรับพ่อแม่ (หายาก)?
เริ่มต้นการใช้งานCWndจัดการกับข้อความต่อไปนี้ และใช้ของ hook OnChildNotifyที่ให้เด็ก windows (ตัวควบคุม) ได้ถอดก่อนที่ข้อความ:
คุณจะสังเกตเห็นของ hook OnChildNotifyที่ใช้สำหรับการเปลี่ยนแปลงข้อความของเจ้าของวาดรูปลงในข้อความ self-draw?
นอกจากการของ hook OnChildNotifyข้อความเลื่อนมีลักษณะการทำงานเพิ่มเติมสายงานการผลิต โปรดดูด้านล่างสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับแถบเลื่อนและแหล่งที่มาของข้อความที่WM_HSCROLLและWM_VSCROLL?
ปัญหา CFrameWnd
คลาCFrameWndสั่งสายงานการผลิตและส่วนติดต่อผู้ใช้ส่วนใหญ่ให้ปรับปรุงการใช้งาน นี้ใช้เป็นหลักสำหรับหน้าต่างเฟรมหลักของแอพลิเคชัน (CWinApp::m_pMainWnd) แต่นำไปใช้กับ windows เฟรมทั้งหมด?
หน้าต่างเฟรมหลักหน้าต่างแถบเมนู และเป็นแม่ของแถบสถานะ หรือข้อความบรรทัด โปรดดูการอภิปรายข้างบนคำสั่งการกำหนดเส้นทาง และWM_INITMENUPOPUP.
คลาCFrameWndให้การจัดการของมุมมองใช้งานอยู่ ข้อความต่อไปนี้จะส่งผ่านมุมมองใช้งานอยู่:
ปัญหา CMDIFrameWnd/CMDIChildWnd
ทั้ง MDI กรอบหน้าต่างชั้นที่สืบทอดมาจากCFrameWndและเปิดจึง เป็นทั้งสองใช้สำหรับการเรียงลำดับของคำสั่งการกำหนดเส้นทางและปรับปรุงส่วนติดต่อผู้ใช้ไว้ในCFrameWndเดียวกัน ในโปรแกรมประยุกต์ MDI ทั่วไป เฉพาะเฟรมหลักหน้าต่าง (นั่นคือ วัตถุCMDIFrameWnd ) เก็บแถบเมนูและแถบสถานะ และดังนั้นจึง เป็นหลักแหล่งมาของคำสั่งใช้งานสายงานการผลิต?
แบบสายงานการผลิตทั่วไปคือ MDI เด็กหน้าต่างที่ใช้งานรับแรกแตกที่คำสั่ง ฟังก์ชันPreTranslateMessageเริ่มต้นจัดการลัดตารางทั้งสองหน้าต่างลูก MDI (ครั้งแรก) และเฟรม MDI (ที่สอง) ตลอดจน MDI ระบบสั่ง accelerators มาตรฐานปกติจัดการโดยTranslateMDISysAccel (โรงแรม)?
ปัญหาของแถบเลื่อน
การจัดการข้อความเลื่อน (WM_HSCROLL/OnHScrollและ/หรือWM_VSCROLL/OnVScroll ), คุณควรลองเขียนรหัสตัวจัดการเพื่อที่จะไม่พึ่งซึ่งข้อความแถบเลื่อนมาจาก นี้ไม่เพียงเป็นทั่วไป Windows ปัญหา เนื่องจากข้อความเลื่อนสามารถมา จากแถบควบคุมจริงเลื่อน หรือจากWS_HSCROLL/WS_VSCROLLแถบเลื่อนที่อยู่ไม่เลื่อนแถบควบคุม?
MFC ขยายที่จะอนุญาตให้ตัวควบคุมแถบเลื่อนจะ เป็นเด็กหรือ siblings ของหน้าต่างที่ไม่ได้เลื่อน (ในความเป็นจริงความสัมพันธ์แม่/เด็กระหว่างแถบเลื่อนและกำลังได้เลื่อนหน้าต่างสามารถเป็นอะไรก็ได้) สิ่งนี้สำคัญอย่างยิ่งสำหรับแถบเลื่อนที่ใช้ร่วมกันกับ windows แยก กรุณาอ้างอิงถึง29 หมายเหตุทางเทคนิคสำหรับรายละเอียดเกี่ยวกับการใช้งานCSplitterWndรวมทั้งข้อมูลเพิ่มเติมเกี่ยวกับปัญหาต่าง ๆ แถบเลื่อนที่ใช้ร่วมกัน?
ในหมายเหตุด้าน มีสองCWndคลาสที่ได้รับมาซึ่งลักษณะแถบเลื่อนที่ระบุไว้ที่สร้างเวลาติดอยู่ และไม่ได้ส่งผ่านไปยัง Windows เมื่อผ่านไปสร้างรูทีนWS_HSCROLLและWS_VSCROLLสามารถแยกตั้ง แต่หลัง จากที่สร้างไม่สามารถเปลี่ยนได้ แน่นอน คุณควรโดยตรงไม่ทดสอบ หรือตั้งค่าการ WS_เลื่อนบิตลักษณะของหน้าต่างที่พวกเขาสร้างขึ้น?
สำหรับCMDIFrameWndลักษณะแถบเลื่อนคุณส่งผ่านในการสร้างหรือLoadFrameใช้ในการสร้าง MDICLIENT ถ้าคุณต้องการให้มีการเลื่อน MDICLIENT พื้นที่ (เช่นเดียวกับที่ Windows Program Manager) ให้แน่ใจว่าการตั้งค่า ทั้งเลื่อนแถบลักษณะ (WS_HSCROLL | WS_VSCROLL) ลักษณะที่ใช้ในการสร้างCMDIFrameWnd?
สำหรับCSplitterWndลักษณะแถบเลื่อนใช้แถบเลื่อนที่ใช้ร่วมกันที่พิเศษสำหรับขอบเขตของการแยก สำหรับ windows คงแยก คุณจะกำหนดลักษณะแถบใดเลื่อนไม่ปกติ สำหรับแยกสัญญาณแบบไดนามิก windows คุณจะมีการเลื่อนแถบชุดลักษณะทิศทางคุณจะแบ่ง กล่าวคือWS_HSCROLLหากคุณสามารถแยกแถวWS_VSCROLLหากคุณสามารถแยกคอลัมน์?
หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)