Passo 4: Modifica del codice di disegno

Nel codice di disegno che si utilizzerà il peccato e cos funzioni per calcolare i punti del poligono, quindi aggiungere includono Math nella parte superiore della PolyCtl. H:

# include lt;math.h >
# include "Resource" / / main simboli

&Nota per il rilascio si basa solonbsp;  Quando la creazione guidata applicazione COM ATL genera il progetto predefinito, definisce la macro ATL_MIN_CRT. Questa macro è definita in modo che non portano la libreria di runtime c nel vostro codice se non lo avete bisogno. Il controllo polygon ha bisogno il codice di libreria di runtime c start-up per inizializzare le funzioni a virgola mobile. Pertanto, è necessario rimuovere la macro ATL_MIN_CRT se volete costruire una versione finale. Per rimuovere la macro, fare clic su impostazioni dal menu progetto . Nella impostazioni per: discesa dell'elenco, scegliere Configurazioni Multiple. Nella finestra selezionare il progetto configuration(s) per modificare di dialogo che viene visualizzata, fare clic sulle caselle di controllo per tutte le quattro versioni di rilascio, quindi scegliere OK. Nella scheda C/C++ , scegliere la categoria generale , quindi rimuovere ATL_MIN_CRT dalla casella di modifica definizioni per il preprocessore.

Una volta che vengono calcolati i punti del poligono, si memorizzano i punti con l'aggiunta di una matrice di tipo POINT fino alla fine della definizione della classe in PolyCtl. H:

   M_clrFillColor OLE_COLOR;
   m_nSides breve;
   PUNTO m_arrPoint [100]

Ora cambiare il OnDraw funzione in PolyCtl. H per abbinare quella qui sotto. Si noti che rimuovere le chiamate alle funzioni rettangolo e DrawText. Puoi anche esplicitamente ottenere e selezionare un pennello bianco e una penna nera. Bisogno di farlo nel caso in cui il controllo è in esecuzione senza finestre. Se non avete la vostra propria finestra, non si possono fare ipotesi circa il contesto di periferica che si potrai essere disegnando.

Completato OnDraw assomiglia a questo:

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 si traducono in un tipo COLORREF
   OleTranslateColor (m_clrFillColor, NULL & colFore);

/ / Crea e selezionare i colori per disegnare il cerchio
   hPen = (HPEN)GetStockObject(BLACK_PEN);
   hOldPen = SelectObject (HPEN) (hdc, hPen);
   hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
   hOldBrush = SelectObject (HBRUSH) (hdc, hBrush);

Ellisse (hdc, rc.left, rc.top, rc.right, rc.bottom);

/ / Crea e selezionate il pennello che verrà utilizzato per riempire il poligono
   hBrush = CreateSolidBrush(colFore);
   SelectObject (hdc, hBrush);

CalcPoints(rc);
   Poligono (hdc & m_arrPoint [0], m_nSides);

/ / Seleziona di nuovo la vecchia penna e pennello ed elimina il pennello abbiamo creato
   SelectObject (hdc, hOldPen);
   SelectObject (hdc, hOldBrush);
   DeleteObject(hBrush);

restituisce S_OK;
}

Ora è &necessario aggiungere una funzione, denominata CalcPoints , che calcola le coordinate della linea intersections.nbsp; Questi calcoli si baserà sulla variabile RECT passato nella funzione.  Innanzitutto si deve aggiungere la definizione di CalcPoints alla sezione pubblica per la classe IPolyCtl in PolyCtl. H:

voidnbsp;   CalcPoints (RECT const & rc)

Sezione pubblica della classe IPolyCtl ora dovrebbe essere simile a questo:

/ / IPolyCtl
pubblica:
   STDMETHOD(get_Sides) (/ * [out, retval] * / cortometraggio * newVal);
   STDMETHOD(put_Sides) (/ * [in] * corta newVal);
   voidnbsp;   CalcPoints (RECT const & rc)

Successivamente, aggiungere l'implementazione del CalcPoints funzione alla fine del file PolyCtl:

public static void CPolyCtl::CalcPoints (const RECTamp; rc)
{
   const double pi = 3.14159265358979;
   PUNTO ptCenter;
   doppia dblRadiusx = (rc.right - rc.left) / 2;
   doppia dblRadiusy = (rc.bottom - rc.top) / 2;
   doppia dblAngle = 3 * pi / 2;          / / Inizia alla parte superiore
   doppia dblDiff = 2 * pi / m_nSides;   / / Angolo di ogni lato renderà
   ptCenter.x = (rc.left + rc.right) / 2;
   ptCenter.y = (rc.top + rc.bottom) / 2;

/ / Calcolare i punti per ogni lato
   per (int i = 0; i < m_nSides; i + +)
   {
      m_arrPoint [i]. x = (long) (dblRadiusx * cos(dblAngle) + ptCenter.x + 0,5);
      .y m_arrPoint [i] = (long) (dblRadiusy * sin(dblAngle) + ptCenter.y + 0,5);
      dblAngle + = dblDiff;
   }
}

Ora, inizializzare m_clrFillColor . Scegli il verde come colore predefinito e aggiungere questa linea per il CPolyCtl Costruttore in PolyCtl. H:

   m_clrFillColor = RGB (0, 0xFF, 0)

Costruttore ora assomiglia a questo:

CPolyCtl()
{
   m_nSides = 3;
   m_clrFillColor = RGB (0, 0xFF, 0);
}

Ora ricostruire il controllo e prova di nuovo. Aprire ActiveX Control Test Container e inserire il controllo. Si dovrebbe vedere un triangolo verde all'interno di un cerchio. Provare a cambiare il numero di lati seguendo la procedura descritta qui sotto. Per modificare le proprietà su un'interfaccia duale all'interno di Test Container, utilizzare Metodi Invoke:

  1. In Test Container, fare clic su Metodi Invoke dal menu di controllo .
    Viene visualizzata la finestra di dialogo Metodo Invoke..

  2. Fare clic sulla versione PropPut della proprietà Sides dal Nome del metodo.

  3. Tipo 5 nella casella di modifica Il valore del parametro , fare clic su Imposta valore e fare clic su richiama.

Si noti che il controllo non cambia. Cosa c'è che non va? Anche se si è modificato il numero di lati internamente impostando il m_nSides variabile, non provocare il controllo di ridipingere. Se si passa a un'altra applicazione e quindi passare al Test Container troverete che il controllo è riverniciato e ora ha il corretto numero di lati.

Per correggere questo problema, è necessario aggiungere una chiamata alla funzione FireViewChange , che è definita in IViewObjectExImpl, dopo aver impostato il numero di lati. Se il controllo è in esecuzione in una finestra separata, FireViewChange chiamerà InvalidateRect API direttamente. Se il controllo viene eseguito senza finestre, il metodo InvalidateRect si chiamerà sull'interfaccia del sito del contenitore. Questo costringe il controllo venga ridisegnato.

Il nuovo put_Sides è riportato il metodo:

STDMETHODIMP CPolyCtl::put_Sides(short newVal)
{
   Se (newVal gt; 2 & & newVal < 101)
   {
      m_nSides = newVal;
      FireViewChange();
      restituisce S_OK;
   }
   altro
      restituire l'errore ( t ("forma deve avere tra i lati 3 e 100"));
}

Dopo aver aggiunto FireViewChange, ricostruire e riprovare il controllo. Questa volta, quando si cambia il numero di lati e scegliere Invoke, si dovrebbe vedere il controllo cambiare immediatamente.

Successivamente, si aggiungerà un evento al controllo.

Torna a passo 3 |nbsp; Al passaggio 5

Index