ขั้นตอนที่ 4: การเปลี่ยนรหัสรูปวาด

ในโค้ดรูปวาดที่คุณจะใช้ฟังก์ชัน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และแทรกตัวควบคุม คุณจะเห็นรูปสามเหลี่ยมสีเขียวภายในวงกลม ลองเปลี่ยนจำนวนของด้านข้างตามขั้นตอนด้านล่างนี้ เมื่อต้องการปรับเปลี่ยนคุณสมบัติบนอินเทอร์เฟซแบบคู่จากภายในคอนเทนเนอร์ทดสอบใช้วิธีการเรียกใช้:

  1. ในการทดสอบคอนเทนเนอร์คลิกวิธีที่เรียกใช้บนเมนูตัวควบคุม
    การเรียกใช้เมธอดจะแสดงกล่องโต้ตอบ?

  2. คลิกคุณสมบัติด้านจากเมธอดชื่อรุ่น PropPut?

  3. พิมพ์ 5 ในกล่องแก้ไขค่าพารามิเตอร์คลิกกำหนดค่าและคลิกInvoke?

ข้อสังเกตที่ตัวควบคุมไม่เปลี่ยนแปลง มีอะไรผิดปกติ แม้ว่าคุณเปลี่ยนจำนวนข้างภายใน โดยการตั้งค่า 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)

Index