ภาพรวมของอินเทอร์เฟซสำหรับ IDispatch OLE
อินเทอร์เฟซสำหรับIDispatchเป็นพาหนะที่ใช้ โดยโปรแกรมประยุกต์ expose วิธีและคุณสมบัติเช่นที่สามารถทำการโปรแกรมประยุกต์ที่อื่น ๆ เช่น Visual BASIC หรือภาษาอื่น ๆ ใช้คุณลักษณะของโปรแกรมประยุกต์ ส่วนสำคัญที่สุดของอินเทอร์เฟซนี้คือ ฟังก์ชันIDispatch::Invoke MFC ใช้ "ส่งแผนที่" ใช้IDispatch::Invoke สรุปข้อมูลแผนที่ให้ข้อมูลการใช้งาน MFC บนเค้าโครงหรือ "ร่าง" ของคุณCCmdTarget-มาเรียน ซึ่งมันสามารถตรงจัดการคุณสมบัติของวัตถุ หรือเรียกสมาชิกฟังก์ชันภายในวัตถุของคุณเพื่อตอบสนองการร้องขอIDispatch::Invoke?
ร่วมส่วนใหญ่ ClassWizard และ MFC มือการซ่อนรายละเอียดของ OLE automation จากโปรแกรมเมอร์ที่โปรแกรมประยุกต์ส่วนใหญ่ โปรแกรมเมอร์ที่ concentrates บนหน้าที่การใช้งานจริงเพื่อนำออกแสดงในแอปพลิเคชัน และไม่ต้องกังวลเกี่ยวกับการกลายเป็นต้น?
มีกรณี อย่างไรก็ตาม ซึ่งจะต้องทำความเข้าใจเกี่ยวกับ MFC ทำอะไรอยู่เบื้องหลัง หมายเหตุนี้จะอยู่อย่างไรกรอบกำหนดDISPIDs ให้สมาชิกฟังก์ชันและคุณสมบัติ ความรู้ของอัลกอริทึมใช้สำหรับการกำหนดDISPIDs MFC เฉพาะจำเป็นเมื่อคุณจำเป็นต้องทราบรหัส เช่นเมื่อคุณสร้าง "ชนิดไลบ" สำหรับวัตถุของโปรแกรมประยุกต์ของคุณ?
การกำหนด MFC DISPID
แม้ว่าผู้ใช้งานของระบบอัตโนมัติ (ผู้ Visual Basic ใช้ ตัวอย่าง), เห็นชื่อแท้จริงของ การทำงานอัตโนมัติเปิดใช้งานคุณสมบัติและวิธีการในโค้ดของพวกเขา (เช่น obj.ShowWindow), การใช้งานIDispatch::Invokeไม่ได้รับชื่อแท้จริง เพื่อให้เหมาะสมเหตุผล ได้รับการDISPIDซึ่งเป็น 32 บิต "วิเศษคุกกี้" ที่อธิบายถึงวิธีการหรือคุณสมบัติซึ่งจะสามารถเข้าถึง มีคืนค่าDISPIDเหล่านี้จากการใช้งานIDispatchผ่านเมธอดอื่น การเรียกว่าIDispatch::GetIDsOfNames โปรแกรมประยุกต์ของไคลเอ็นต์อัตโนมัติจะเรียกGetIDsOfNamesหนึ่งครั้งสำหรับแต่ละสมาชิกหรือคุณสมบัติมัน intends เข้า และใช้แคชกับเหล่านั้นในภายหลังเรียกไปยังIDispatch::Invoke วิธีนี้ การค้นหาสายอักขระที่แพงเท่านั้นเสร็จหนึ่งครั้งสำหรับแต่ละวัตถุที่ใช้ แทนครั้งต่อIDispatch::Invoke?
MFC s DISPIDสำหรับแต่ละเมธอดและคุณสมบัติที่ยึดตามสิ่งที่สองที่กำหนด:
DISPIDถูกแบ่งออกเป็นสองส่วน LOWORDของDISPIDประกอบด้วยองค์ประกอบแรก ระยะห่างจากด้านบนของแผนที่ส่ง HIWORDประกอบด้วยระยะห่างจากระดับชั้นได้รับมากที่สุด ตัวอย่างเช่น:
คลา CDispPoint: CCmdTarget สาธารณะ
{
สาธารณะ:
nbsp สั้น m_x, m_y
...
DECLARE_DISPATCH_MAP()
...
};
คลา CDisp3DPoint: CDispPoint สาธารณะ
{
สาธารณะ:
m_y ย่อ
...
DECLARE_DISPATCH_MAP()
...
};
BEGIN_DISPATCH_MAP (CDispPoint, CCmdTarget)
DISP_PROPERTY (CDispPoint, "x", m_x, VT_I2)
DISP_PROPERTY (CDispPoint, "y", m_y, VT_I2)
END_DISPATCH_MAP()
BEGIN_DISPATCH_MAP (CDisp3DPoint, CDispPoint)
DISP_PROPERTY (CDisp3DPoint, "z", m_z, VT_I2)
END_DISPATCH_MAP()(&N)
คุณสามารถเห็นได้ มีสองชั้น ทั้งสองอย่างซึ่งทำให้อินเทอร์เฟซของ OLE automation เรียนเหล่านี้ได้รับมาจากอื่น ๆ และ leverages ดังนั้น ฟังก์ชันของคลาส base รวมทั้งส่วน OLE automation ("x" และ "y" คุณสมบัติในกรณีนี้)?
MFC จะสร้างDISPIDs สำหรับคลาส CDispPoint เป็นดังนี้:
คุณสมบัติ Xnbsp (DISPID) 0X00000001
คุณสมบัติ Y (DISPID) 0x00000002(&N)
เนื่องจากคุณสมบัติไม่ได้อยู่ในคลาสพื้นฐานHIWORDของDISPIDจะเป็นศูนย์เสมอ (ระยะห่างจากระดับชั้นได้รับมากที่สุดสำหรับ CDispPoint เป็นศูนย์)?
MFC จะสร้างDISPIDs สำหรับคลาส CDisp3DPoint เป็นดังนี้:
คุณสมบัติ Znbsp (DISPID) 0X00000001
คุณสมบัติ X (DISPID) 0x00010001
คุณสมบัติ Y (DISPID) 0x00010002(&N)
คุณสมบัติ' Z 'ถูกกำหนดเป็นDISPIDกับการเป็นศูนย์HIWORDเนื่องจากมีกำหนดในชั้นเรียนซึ่งจะมีการเปิดเผยคุณสมบัติ CDisp3DPoint เนื่องจากมีกำหนดคุณสมบัติของ X และ Y ในคลาสพื้นฐานHIWORDของDISPIDคือ 1 ตั้งแต่ชั้นในซึ่งคุณสมบัติเหล่านี้ถูกกำหนดเป็นระยะทางหนึ่งที่มาจากระดับชั้นได้รับมากที่สุด?
หมายเหตุnbspLOWORDจะเสมอถูกกำหนด โดยตำแหน่งในแผนผัง แม้ว่าจะมีรายการในแมปกับชัดเจนDISPID (ดูส่วนถัดไปสำหรับข้อมูลบนแมโคDISP_PROPERTYและDISP_FUNCTIONรุ่น_ID )(&N)?
MFC สรุปข้อมูลแผนที่คุณลักษณะขั้นสูง
มีตัวเลขของคุณลักษณะเพิ่มเติมที่ ClassWizard ไม่สนับสนุน โดยรุ่นนี้ของ Visual c ++ ClassWizard สนับสนุนDISP_FUNCTION, DISP_PROPERTYและDISP_PROPERTY_EXซึ่งกำหนดเป็นวิธี คุณสมบัติตัวแปรของสมาชิก และ คุณสมบัติฟังก์ชันการสมาชิกรับ/ชุด ตามลำดับ ความสามารถเหล่านี้มักทั้งหมดที่จำเป็นในการสร้างส่วนใหญ่ทำงานอัตโนมัติเซิร์ฟเวอร์?
แมโครที่เพิ่มเติมต่อไปนี้สามารถใช้ได้เมื่อแมโค ClassWizard ที่ได้รับการสนับสนุนไม่เพียงพอ: DISP_PROPERTY_NOTIFYและDISP_PROPERTY_PARAM?
DISP_PROPERTY_NOTIFY คำอธิบายของแมโคร
DISP_PROPERTY_NOTIFY (pszName,memberName,pfnAfterSet,theClass,vtPropType)
theClass
ชื่อของระดับชั้น?
pszName
ชื่อของคุณสมบัติที่ภายนอก?
memberName
ชื่อของตัวแปรของสมาชิกที่จะถูกเก็บในคุณสมบัติ?
pfnAfterSet
ชื่อของฟังก์ชันของสมาชิกเพื่อที่เรียกใช้เมื่อมีการเปลี่ยนแปลงคุณสมบัติ?
vtPropType
ค่าระบุชนิดของคุณสมบัติ?
หมายเหตุnbsp แมโครนี้จะมากเช่นDISP_PROPERTYยกเว้นให้ยอมรับอาร์กิวเมนต์เพิ่มเติม อาร์กิวเมนต์เพิ่มเติมpfnAfterSetควรเป็นสมาชิกฟังก์ชันที่ส่งกลับไม่มีอะไร และจะไม่มีพารามิเตอร์ 'โมฆะ OnPropertyNotify()' มันจะมีชื่อว่าหลังจากมีการปรับเปลี่ยนตัวแปรของสมาชิก(&N)?
DISP_PROPERTY_PARAM คำอธิบายของแมโคร
DISP_PROPERTY_PARAM (theClass, pszName, pfnGet, pfnSet, vtPropType, vtsParams)
theClass
ชื่อของระดับชั้น?
pszName
ชื่อของคุณสมบัติที่ภายนอก?
memberGet
ชื่อของฟังก์ชันสมาชิกใช้ในการรับคุณสมบัติ?
memberSet
ชื่อของฟังก์ชันสมาชิกใช้ในการตั้งค่าคุณสมบัติ?
vtPropType
ค่าระบุชนิดของคุณสมบัติ?
vtsParams
สายอักขระว่าง VTS_ ที่แยกจากกันสำหรับแต่ละพารามิเตอร์?
หมายเหตุnbsp มากเช่นเดียวกับแมโคDISP_PROPERTY_EXแมโครนี้กำหนดคุณสมบัติ ด้วยต่างหาก Get Set สมาชิกฟังก์ชันและการเข้าถึง แมโครนี้ อย่างไรก็ตาม ช่วยให้คุณระบุรายการพารามิเตอร์สำหรับคุณสมบัตินี้ ซึ่งเป็นประโยชน์สำหรับการใช้คุณสมบัติที่มีการจัดทำดัชนี หรือกำหนดค่าพารามิเตอร์ในบางวิธีอื่น ๆ พารามิเตอร์จะเสมออยู่ก่อน แล้วตาม ด้วยค่าใหม่สำหรับคุณสมบัติ ตัวอย่างเช่น(&N):
DISP_PROPERTY_PARAM (CMyObject "สินค้า" GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)
ต้องสอดคล้องกับรับ และการตั้งค่าฟังก์ชันของสมาชิก:
LPDISPATCH CMyObject::GetItem(short row, short col)
โมฆะ CMyObject::SetItem (สั้นแถว คอลัมน์ย่อ LPDISPATCH newValue)
DISP_XXXX_ID คำอธิบายของแมโคร
DISP_FUNCTION_ID (theClass, pszName, dispid, pfnMember, vtRetVal, vtsParams)
DISP_PROPERTY_ID (theClass, pszName, dispid, memberName, vtPropType)
DISP_PROPERTY_NOTIFY_ID (theClass, pszName, dispid, memberName, pfnAfterSet, vtPropType)
DISP_PROPERTY_EX_ID (theClass, pszName, dispid, pfnGet, pfnSet, vtPropType)
DISP_PROPERTY_PARAM_ID (theClass, pszName, dispid, pfnGet, pfnSet, vtPropType, vtsParams)
theClass
ชื่อของระดับชั้น?
pszName
ชื่อของคุณสมบัติที่ภายนอก?
dispid
DISPID ที่ถาวรสำหรับคุณสมบัติหรือเมธอด?
pfnGet
ชื่อของฟังก์ชันสมาชิกใช้ในการรับคุณสมบัติ?
pfnSet
ชื่อของฟังก์ชันสมาชิกใช้ในการตั้งค่าคุณสมบัติ?
memberName
ชื่อของตัวแปรสมาชิกจะใช้แมปไปยังคุณสมบัติ
vtPropType
ค่าระบุชนิดของคุณสมบัติ?
vtsParams
สายอักขระว่าง VTS_ ที่แยกจากกันสำหรับแต่ละพารามิเตอร์?
หมายเหตุnbsp แมโครเหล่านี้อนุญาตให้คุณระบุDISPIDแทนของ MFC ที่กำหนดโดยอัตโนมัติอย่างใดอย่างหนึ่งให้ แมโครการขั้นสูงเหล่านี้มีชื่อเดียวกันยกเว้น ID ที่จะถูกผนวกเข้ากับชื่อแมโคร (เช่นDISP_PROPERTY_ID) และ ID ถูกกำหนด โดยพารามิเตอร์ระบุไว้หลังจากพารามิเตอร์pszName ดู AFXDISPสำหรับข้อมูลเพิ่มเติมเกี่ยวกับแมโครเหล่านี้ H _IDรายการต้องอยู่ที่ท้ายของแผนที่ส่ง พวกเขาจะมีผลต่อการสร้างDISPIDแบบอัตโนมัติในแบบเดียวกับไม่ใช่ -_IDรุ่นของแมโครที่จะ (s DISPIDถูกกำหนด โดยตำแหน่ง) ตัวอย่างเช่น(&N):
BEGIN_DISPATCH_MAP (CDisp3DPoint, CCmdTarget)
nbsp DISP_PROPERTY (CDisp3DPoint, "y", m_y, VT_I2)
DISP_PROPERTY (CDisp3DPoint, "z", m_z, VT_I2)
DISP_PROPERTY_ID (CDisp3DPoint, "x", 0x00020003, m_x, VT_I2)
END_DISPATCH_MAP()(&N)
MFC จะสร้าง DISPIDs สำหรับคลาส CDisp3DPoint เป็นดังนี้:
คุณสมบัติ Xnbsp (DISPID) 0X00020003
คุณสมบัติ Y (DISPID) 0x00000002
คุณสมบัติ Z (DISPID) 0x00000001(&N)
ระบุแบบถาวรDISPIDมีประโยชน์ในการรักษาย้อนหลังเข้ากันได้ในอินเทอร์เฟซการสรุปข้อมูลที่มีอยู่ก่อนหน้านี้ หรือระบบบางอย่างที่นำมาใช้กำหนดวิธีการหรือคุณสมบัติ (โดยปกติจะระบุโดยการลบDISPIDเช่นคอลเลกชันDISPID_NEWENUM )?
เรียกอินเทอร์เฟซสำหรับ IDispatch สำหรับการ COleClientItem
เซิร์ฟเวอร์หลายจะสนับสนุนการทำงานอัตโนมัติภายในวัตถุของเอกสาร พร้อมกับการทำงานของเซิร์ฟเวอร์ OLE เพื่อที่จะสามารถเข้าถึงอินเทอร์เฟซนี้อัตโนมัติ เป็นความจำเป็นในการเข้าถึงโดยตรงตัวแปรสมาชิกCOleClientItem::m_lpObject โค้ดด้านล่างจะเรียกอินเทอร์เฟซสำหรับIDispatchสำหรับวัตถุที่ได้มาจากCOleClientItem คุณสามารถรวมรหัสด้านล่างในโปรแกรมประยุกต์ของคุณถ้าคุณพบฟังก์ชันนี้จำเป็น
LPDISPATCH CMyClientItem::GetIDispatch()
{
nbsp ASSERT_VALID(this)
ASSERT (m_lpObject ! = NULL);
LPUNKNOWN lpUnk = m_lpObject
Run() / / ต้องทำงาน
LPOLELINK lpOleLink = NULL
ถ้า (m_lpObject - > QueryInterface (IID_IOleLink, (LPVOID ไกล *) & lpOleLink) == NOERROR)
{
ASSERT (lpOleLink ! = NULL);
lpUnk = NULL
ถ้า (lpOleLink - > GetBoundSource(&lpUnk) ! = NOERROR)
{
TRACE0 ("คำเตือน: การเชื่อมโยงที่มีการเชื่อมต่อไม่! \n ");
lpOleLink - > Release()
ส่งกลับค่า NULL
}
ASSERT (lpUnk ! = NULL);
}
LPDISPATCH lpDispatch = NULL
ถ้า (lpUnk - > QueryInterface (IID_IDispatch และ lpDispatch) ! = NOERROR)
{
TRACE0 ("คำเตือน: ไม่สนับสนุน IDispatch ! \n ");
ส่งกลับค่า NULL
}
ASSERT (lpDispatch ! = NULL);
กลับ lpDispatch
}
อินเทอร์เฟซสำหรับการจัดส่งที่ส่งคืนจากฟังก์ชันนี้ได้แล้วสามารถใช้ได้โดยตรง หรือแนบกับCOleDispatchDriverสำหรับการเข้าถึงชนิดเซฟได้ ถ้าคุณใช้มันโดยตรง ตรวจสอบให้แน่ใจว่า คุณเรียกสมาชิกออกเมื่อผ่าน ด้วยตัวชี้ (destructor COleDispatchDriverที่ไม่นี้ตามค่าเริ่มต้น)?
หมายเหตุด้านเทคนิคตามหมายเลข|nbsp หมายเหตุด้านเทคนิคตามประเภท(&N)