ในโค้ดรูปวาดที่คุณจะใช้ฟังก์ชันsinและcosเพื่อคำนวณจุดรูปหลายเหลี่ยม ดังนั้น เพิ่มรวม math.h ด้านบนของ PolyCtl.h:
#รวม lt;math.h >
#รวม "resource.h" / / หลักสัญลักษณ์
หมายเหตุสำหรับรุ่นสร้างเฉพาะnbsp เมื่อ AppWizard COM ATL สร้างโครงการเริ่มต้น กำหนดที่แมโค_ATL_MIN_CRT แมโครนี้ถูกกำหนดขึ้นเพื่อให้คุณไม่นำไลบรารีรันไทม์ C ไว้ในรหัสของคุณถ้าคุณไม่จำเป็น ตัวควบคุมรูปหลายเหลี่ยมต้องรหัส C ขณะใช้งานไลบรารีเริ่มต้นเตรียมใช้งานฟังก์ชันทศนิยม ดังนั้น คุณจำเป็นต้องลบแมโค_ATL_MIN_CRTถ้าคุณต้องการสร้างรุ่น Release การลบแมโคร คลิกSettingsในเมนูโครงการ ในการการตั้งค่าสำหรับ:แบบหล่นลงรายการ เลือกการตั้งค่าคอนฟิกหลาย ในโครงการ configuration(&s) เพื่อปรับเปลี่ยนเลือกกล่องโต้ตอบที่ปรากฏ คลิกที่กล่องกาเครื่องหมายสำหรับรุ่นสี่ทั้งหมด แล้วคลิกตกลง บนแท็บC/c ++เลือกประเภททั่วไปแล้วเอา_ATL_MIN_CRTออกจากกล่องแก้ไขข้อกำหนด Preprocessor?
เมื่อจุดของรูปหลายเหลี่ยมมีคำนวณ คุณเก็บจุด โดยการเพิ่มอาร์เรย์ของชนิดจุดส่วนท้ายของคำจำกัดความของคลาสใน PolyCtl.h:
OLE_COLOR m_clrFillColor
m_nSides ย่อ
จุด m_arrPoint [100]
ขณะนี้ มีการเปลี่ยนแปลงการ OnDraw ฟังก์ชันใน PolyCtl.h ให้ตรงกับด้านล่าง หมายเหตุว่า คุณเอาการเรียกฟังก์ชันสี่เหลี่ยมและ DrawText คุณยังอย่างชัดเจนได้รับ และเลือกปากกาสีดำและสีขาวแปรง คุณต้องการทำเช่นนี้ในกรณีที่ตัวควบคุมของคุณกำลังทำงานแบบไม่มีหน้าต่าง ถ้าคุณไม่มีหน้าต่างของคุณเอง คุณไม่สามารถทำสมมติฐานเกี่ยวกับบริบทอุปกรณ์ที่คุณจะสามารถวาดภาพใน?
ที่เสร็จสมบูรณ์ OnDraw ลักษณะเช่นนี้:
Hresult ใน CPolyCtl::OnDraw(ATL_DRAWINFOamp; di)
{
RECT & rc = *(RECT*)di.prcBounds;
HDC hdc = di.hdcDraw
COLORREF colFore
HBRUSH hOldBrush, hBrush
HPEN hOldPen, hPen
/ / แปล m_colFore เป็นชนิด COLORREF
OleTranslateColor (m_clrFillColor, NULL และ colFore);
/ / สร้าง และเลือกสีเมื่อต้องการวาดวงกลม
hPen = (HPEN)GetStockObject(BLACK_PEN)
hOldPen = SelectObject (HPEN) (hdc, hPen);
hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH)
hOldBrush = SelectObject (HBRUSH) (hdc, hBrush);
วงรี (hdc, rc.left, rc.top, rc.right, rc.bottom);
/ / สร้าง และเลือกแปรงที่จะใช้การเติมรูปหลายเหลี่ยม
hBrush = CreateSolidBrush(colFore)
SelectObject (hdc, hBrush);
CalcPoints(rc)
รูปหลายเหลี่ยม (m_nSides hdc และ m_arrPoint [0],);
/ / เลือกหลังเก่าปากกาและแปรง และลบแปรงเราสร้าง
SelectObject (hdc, hOldPen);
SelectObject (hdc, hOldBrush);
DeleteObject(hBrush)
กลับ S_OK
}
ขณะนี้คุณต้องการเพิ่มฟังก์ชัน เรียกว่า CalcPoints ที่จะคำนวณพิกัดของบรรทัด intersections.nbsp คำนวณเหล่านี้จะยึดตามตัวแปร RECT ที่ถูกส่งไปยังฟังก์ชัน อันดับแรก คุณควรเพิ่มคำจำกัดความของ CalcPoints ที่ส่วนสาธารณะสำหรับคลาส IPolyCtl ใน PolyCtl.h(&N):
voidnbsp CalcPoints (const RECT & rc)
ส่วนสาธารณะของคลา IPolyCtl ควรมีลักษณะดังนี้:
/ / IPolyCtl
สาธารณะ:
STDMETHOD(get_Sides) (/ * [ออก retval] * / สั้น * newVal);
STDMETHOD(put_Sides) (/ * [ใน] * / สั้น newVal);
voidnbsp CalcPoints (const RECT & rc)
ถัดไป เพิ่มการใช้งาน CalcPoints ฟังก์ชันลงในส่วนท้ายของแฟ้ม PolyCtl.cpp:
โมฆะ CPolyCtl::CalcPoints (const RECTamp; rc)
{
const คู่ pi = 3.14159265358979
จุด ptCenter
คู่ dblRadiusx = (rc.right - rc.left) / 2
คู่ dblRadiusy = (rc.bottom - rc.top) / 2
คู่ dblAngle = 3 * pi / 2 / / เริ่มต้นที่ด้านบน
คู่ dblDiff = 2 * pi / m_nSides / / มุมแต่ละด้านจะทำให้
ptCenter.x = (rc.left + rc.right) / 2
ptCenter.y = (rc.top + rc.bottom) / 2
/ / คำนวณคะแนนได้สำหรับแต่ละด้าน
สำหรับ (int ฉัน = 0 ฉัน < m_nSides; i ++)
{
.x m_arrPoint [i] = (ยาว) (dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5);
m_arrPoint [i] .y = (ยาว) (dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5);
dblAngle += dblDiff
}
}
เตรียมใช้งานขณะนี้ m_clrFillColor เลือกสีเขียวเป็นสีเริ่มต้น และเพิ่มบรรทัดนี้ CPolyCtl กำหนดใน PolyCtl.h:
m_clrFillColor = RGB (0, 0xFF, 0)
พารามิเตอร์ที่ขณะนี้มีลักษณะดังนี้:
CPolyCtl()
{
m_nSides = 3
m_clrFillColor = RGB (0, 0xFF, 0);
}
ขณะนี้การสร้างตัวควบคุมใหม่ และลองอีกครั้ง เปิดตัวบรรจุการทดสอบตัวควบคุม ActiveXและแทรกตัวควบคุม คุณจะเห็นรูปสามเหลี่ยมสีเขียวภายในวงกลม ลองเปลี่ยนจำนวนของด้านข้างตามขั้นตอนด้านล่างนี้ เมื่อต้องการปรับเปลี่ยนคุณสมบัติบนอินเทอร์เฟซแบบคู่จากภายในคอนเทนเนอร์ทดสอบใช้วิธีการเรียกใช้:

ข้อสังเกตที่ตัวควบคุมไม่เปลี่ยนแปลง มีอะไรผิดปกติ แม้ว่าคุณเปลี่ยนจำนวนข้างภายใน โดยการตั้งค่า m_nSides ตัวแปร คุณไม่ได้ทำให้เกิดตัวควบคุมจะวาด ถ้าคุณสลับไปยังโปรแกรมประยุกต์อื่นแล้ว สลับกลับไปยังคอนเทนเนอร์ทดสอบคุณจะค้นหาที่ ตัวควบคุมคือ repainted และขณะนี้ มีจำนวนด้านถูกต้อง?
เมื่อต้องการแก้ไขปัญหานี้ คุณต้องการเพิ่มการเรียกฟังก์ชันFireViewChangeซึ่งกำหนดไว้ในIViewObjectExImplหลังจากที่คุณตั้งค่าหมายเลขของด้าน ถ้าตัวควบคุมจะทำงานในหน้าต่างของตัวเองFireViewChangeจะโทรInvalidateRect API โดยตรง ถ้าตัวควบคุมจะทำงานแบบไม่มีหน้าต่าง จะเรียกเมธอดInvalidateRectบนอินเทอร์เฟซของเว็บไซต์ในคอนเทนเนอร์ นี้บังคับให้ตัวควบคุมจะวาดเอง?
ใหม่ put_Sides วิธีมีดังนี้:
STDMETHODIMP CPolyCtl::put_Sides(short newVal)
{
ถ้า (newVal gt; 2 & & newVal < 101)
{
m_nSides = newVal
FireViewChange()
กลับ S_OK
}
อื่น
ส่งกลับข้อผิดพลาด (_T ("รูปร่างต้องมีระหว่างฝ่ายที่ 3 และ 100"));
}
หลังจากที่คุณได้เพิ่มFireViewChangeสร้างใหม่อีกครั้ง และลองตัวควบคุมอีกครั้ง เวลานี้เมื่อคุณเปลี่ยนจำนวนของด้านข้าง และคลิกInvokeคุณจะเห็นตัวควบคุมเปลี่ยนแปลงทันที?
ถัดไป คุณจะเพิ่มเหตุการณ์ลงในตัวควบคุม?
|Nbspกลับไปยังขั้นตอนที่ 3 ขั้นตอนที่ 5(&N)