ΠΠ΅ΡΡΡ ΠΈ ΠΊΠΈΡΡΠΈ Π²Π½ΡΡΡΠΈ ΠΊΠ»Π°ΡΡΠΎΠ²
Π ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠ΅ΡΡΡΠΌΠΈ ΠΈ ΡΠ°ΡΠΊΡΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ ΠΊΠΈΡΡΡΠΌΠΈΠΠ΅ΡΠ΅Π²ΠΎΠ΄ Π. Π. ΠΠ΅Π³Π°Π»ΠΎΠ²Π°
ΠΠ½Π³Π»ΠΎΡΠ·ΡΡΠ½ΡΠΉ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π» Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Reliable Software
ΠΠΎΠ΄ΠΎΠ±Π½ΠΎ ΠΆΠΈΠ²ΠΎΠΏΠΈΡΡΡ, ΠΡ Π½ΡΠΆΠ΄Π°Π΅ΡΠ΅ΡΡ Π² ΠΏΠ΅ΡΡΡΡ ΠΈ ΠΊΠΈΡΡΡΡ , ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ΅Π΄Π΅Π²Ρ Π½Π° Π²Π°ΡΠ΅ΠΌ Ρ ΠΎΠ»ΡΡΠ΅. ΠΠΎΠ³Π΄Π° ΠΡ Π²ΡΠ·ΡΠ²Π°Π΅ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ Canvas::Line ΠΈΠ»ΠΈ Canvas::Rectangle, Windows ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΠ΅ΠΊΡΡΠΈΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΠΏΠ΅ΡΠ°, ΡΡΠΎΠ±Ρ ΡΠΈΡΠΎΠ²Π°ΡΡ Π»ΠΈΠ½ΠΈΠΈ, ΠΈ ΡΠ΅ΠΊΡΡΠΈΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΠΊΠΈΡΡΠΈ, ΡΡΠΎΠ±Ρ Π·Π°ΠΏΠΎΠ»Π½ΡΡΡ ΠΎΡ Π²Π°ΡΡΠ²Π°Π΅ΠΌΡΠ΅ ΠΊΠΎΠ½ΡΡΡΡ.
ΠΠΎΠ³Π΄Π° ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»ΡΠ΅ΡΡΡ Ρ Π₯ΠΎΠ»ΡΡΠΎΠΌ, Π½Π΅Π»ΡΠ·Ρ Π·Π°Π±ΡΠ²Π°ΡΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ Π΅Π³ΠΎ ΠΏΠΎΡΠ»Π΅ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ. ΠΡΠΎ Π½Π°Π΄ΠΎ Π΄Π΅Π»Π°ΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π²Ρ Π½Π΅ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΠ΅ ΡΠ°ΠΊΠΎΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΡ Π²Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π½Π° ΡΠ·ΡΠΊΠ΅ C++. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠΎΠ»ΡΠΊΠΎ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ, ΡΡΠΈ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΡΡ, Π° Π΄Π΅ΡΡΡΡΠΊΡΠΎΡΡ (Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΠ΅ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ, ΠΏΡΠΈ Π²ΡΡ ΠΎΠ΄Π΅ ΠΎΠ±Π»Π°ΡΡΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ) ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ (ΡΠΌ. ΡΡΡΠ°Π½ΠΈΡΡ Β«Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠ΅ΡΡΡΡΠ°ΠΌΠΈΒ» Π΄Π»Ρ Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ Π·Π½Π°ΠΊΠΎΠΌΡΡΠ²Π° Ρ ΡΡΠΎΠΉ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΠ΅ΠΉ). ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π½ΠΈΠΆΠ΅ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ HDC (Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΠ² ΡΡΡΡΠΎΠΉΡΡΠ²) Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π² ΠΈΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ°Ρ . ΠΠ΄Π½Π°ΠΊΠΎ, Π²Π·Π°ΠΌΠ΅Π½ ΡΡΠΎΠ³ΠΎ, ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ Canvas. ΠΠΎΠΌΠ½ΠΈΡΠ΅, ΡΡΠΎ Β«Π₯ΠΎΠ»ΡΡΒ» ΠΌΠΎΠΆΠ΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡΡΡ ΠΊ HDC.
class StockObject {
public:
StockObject(HDC hdc, int type) : _hdc(hdc) {
_hObjOld = SelectObject(_hdc, GetStockObject(type));
}
~StockObject () {
SelectObject(_hdc, _hObjOld);
}
private:
HGDIOBJ _hObjOld;
HDC _hdc;
};
Windows ΠΈΠΌΠ΅Π΅Ρ Π½Π°Π±ΠΎΡ ΠΏΡΠ΅Π΄ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ ΠΏΠ΅ΡΡΠ΅Π² ΠΈ ΠΊΠΈΡΡΠ΅ΠΉ. ΠΡΠ»ΠΈ ΠΡ Ρ ΠΎΡΠΈΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΡ , ΡΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡΡ Π²ΡΠ±ΡΠ°Π½Π½ΡΠ΅ ΠΏΠ΅ΡΡΡ ΠΈ ΠΊΠΈΡΡΠΈ ΠΊ Π²Π°ΡΠ΅ΠΌΡ Ρ ΠΎΠ»ΡΡΡ Π½Π΅ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠ΅ΠΌΡ.
class WhitePen : public StockObject {
public:
WhitePen(HDC hdc): StockObject(hdc, WHITE_PEN) {}
};
// example
void Controller::Paint(HWND hwnd) {
PaintCanvas canvas(hwnd);
WhitePen pen(canvas);
canvas.Line(0, 10, 100, 10);
// destructor of WhitePen
// destructor of PaintCanvas
}
ΠΡΠ»ΠΈ Π²Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΠ΅ΡΡΠ΅Π², ΠΎΡΡΡΡΡΡΠ²ΡΡΡΠΈΡ Π² Windows, ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΈΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π½Π΅Π΄ΡΠΈΠ² ΠΈΡ Π² ΠΎΠ±ΡΠ΅ΠΊΡ View) ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ PenHolder, Π΄Π»Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ ΠΊ Π₯ΠΎΠ»ΡΡΡ.
class Pen {
public:
Pen(COLORREF color) {
_hPen = CreatePen(PS_SOLID, 0, color);
}
~Pen() {
DeleteObject(_hpen);
}
operator HPEN() {
return _hPen;
}
private:
HPEN _hPen;
};
class PenHolder {
public:
PenHolder(HDC hdc, HPEN hPen) : _hdc (hdc) {
_hPenOld = (HPEN)SelectObject (_hdc, hPen);
}
~PenHolder() {
SelectObject(_hdc, _hPenOld);
}
private:
HDC _hdc;
HPEN _hPenOld;
};
class View {
public:
View() : _penGreen (RGB (0, 255, 128)) {}
void Paint(Canvas& canvas) {
PenHolder holder(canvas, _penGreen);
canvas.Line(0, 10, 100, 10);
// destructor of PenHolder
}
private:
Pen _penGreen;
};
Π, Π½Π°ΠΊΠΎΠ½Π΅Ρ, Π΅ΡΠ»ΠΈ Π²Π°ΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π½ΡΠΆΠ΄Π°Π΅ΡΡΡ Π² ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΡ ΡΠ²Π΅ΡΠ½ΡΡ ΠΏΠ΅ΡΡΡΡ , ΡΠΎ Π΅ΡΡΡ, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π²ΡΠ΅Ρ ΡΠ²Π΅ΡΠΎΠ², Π² ΠΊΠΎΡΠΎΡΡΡ Π²Ρ Π±ΡΠ΄Π΅ΡΠ΅ Π½ΡΠΆΠ΄Π°ΡΡΡΡ, ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ²Π΅ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΡΡ. ΠΠΎΠ³Π΄Π° ΠΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΠ΅ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ColorPen, Π΅Π³ΠΎ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΡΠΎΠ·Π΄Π°Π΅Ρ ΠΈ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ ΠΏΠ΅ΡΠΎ. ΠΠΎΠ³Π΄Π°, Π² ΠΊΠΎΠ½ΡΠ΅ ΠΎΠ±Π»Π°ΡΡΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ, ΠΎΠ½ ΠΎΡΡΠΎΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ ΠΏΠ΅ΡΠΎ ΠΈ ΡΠ΄Π°Π»ΡΠ΅Ρ Π΅Π³ΠΎ.
class ColorPen {
public:
ColorPen(HDC hdc, COLORREF color) : _hdc (hdc) {
_hPen = CreatePen(PS_SOLID, 0, color);
_hPenOld = (HPEN)SelectObject(_hdc, _hPen);
}
~ColorPen() {
SelectObject(_hdc, _hPenOld);
DeleteObject(_hPen);
}
private:
HDC _hdc;
HPEN _hPen;
HPEN _hPenOld;
};
Π’ΠΎΡΠ½ΠΎ ΡΠ°ΠΊΠΈΠΌ ΠΆΠ΅ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΠΊΠΈΡΡΡΠΌΠΈ (ΠΊΠΈΡΡΠ΅ΠΉ, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΡ Windows, Π³ΠΎΡΠ°Π·Π΄ΠΎ Π±ΠΎΠ»ΡΡΠ΅, ΡΠ΅ΠΌ ΠΏΠ΅ΡΡΠ΅Π²). Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΡΠΈΠΌΠ΅ΡΠ°, Π½ΠΈΠΆΠ΅ Π΄Π°Π΅ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ColorBrush.
class ColorBrush {
public:
ColorBrush(HDC hdc, COLORREF color) : _hdc (hdc) {
_hBrush = CreateSolidBrush(color);
_hBrushOld = (HBRUSH)SelectObject(_hdc, _hBrush);
}
~ColorBrush() {
SelectObject(_hdc, _hBrushOld);
DeleteObject(_hBrush);
}
private:
HDC _hdc;
HBRUSH _hBrush;
HBRUSH _hBrushOld;
};
ΠΠ°ΠΊ Π²ΡΠ΅Π³Π΄Π°, ΠΌΡ ΠΏΠΎΡΡΡΠ΅ΠΌ ΠΠ°ΡΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΡ.
ΠΠ°Π»Π΅Π΅: ΡΠΎΠ²Π΅ΡΡΠ΅Π½Π½ΠΎ ΠΈΠ½Π°Ρ ΡΠ΅ΠΌΠ° β Β«ΠΠΎΡΠΎΠΊΠΈΒ».
ΠΠ»Π°ΡΡΠΎΠ²Π°Ρ ΠΎΠ±ΠΎΠ»ΠΎΡΠΊΠ° Π΄Π»Ρ ΠΏΠΎΡΠΎΠΊΠΎΠ²
ΠΠ΅ΡΠ΅Π²ΠΎΠ΄ Π. Π. ΠΠ΅Π³Π°Π»ΠΎΠ²Π°
ΠΠ½Π³Π»ΠΎΡΠ·ΡΡΠ½ΡΠΉ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π» Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ Reliable Software
ΠΠ½ΠΎΠ³ΠΎΠ·Π°Π΄Π°ΡΠ½ΠΎΡΡΡ β ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΄Π½ΡΡ Π°ΡΠΏΠ΅ΠΊΡΠΎΠ² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΠΎΡΡΠΎΠΌΡ, Π΄Π»Ρ Π½Π΅Π΅ ΡΠ΅ΠΌ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ ΠΏΡΠΎΡΡΠΎΠΉ Π½Π°Π±ΠΎΡ Π°Π±ΡΡΡΠ°ΠΊΡΠΈΠΉ ΠΈ ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΡ Π² Ρ ΠΎΡΠΎΡΠ΅ΠΉ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΎΠ±ΠΎΠ»ΠΎΡΠΊΠ΅. Π ΠΠ ΠΌΠΈΡΠ΅, Π΅ΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ Π°Π½Π°Π»ΠΎΠ³ΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ°, ΡΠ²Π»ΡΡΡΠ΅Π³ΠΎΡΡ, ΡΠΈΡΡΠΎ ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ½ΠΎΠΉ Π°Π±ΡΡΡΠ°ΠΊΡΠΈΠ΅ΠΉ, ΡΠ»ΡΠΆΠΈΡ Β«ΠΠΊΡΠΈΠ²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡΒ». ΠΠΊΡΠΈΠ²Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠΌ ΠΏΠΎΡΠΎΠΊΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ Π·Π°Π΄Π°ΡΠΈ. ΠΡΠΎΡ ΠΏΠΎΡΠΎΠΊ ΠΈΠΌΠ΅Π΅Ρ Π΄ΠΎΡΡΡΠΏ ΠΊ Π²ΡΠ΅ΠΌ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠΌ (Π·Π°ΠΊΡΡΡΡΠΌ) Π΄Π°Π½Π½ΡΠΌ ΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΡΠΊΡΡΡΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π²Π½Π΅ΡΠ½ΠΈΠΌ Π°Π³Π΅Π½ΡΠ°ΠΌ (ΡΠ°ΠΊΠΈΠΌ ΠΊΠ°ΠΊ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ, ΠΈΠ»ΠΈ ΠΏΠΎΡΠΎΠΊΡ, Π½Π΅ΡΡΡΠ΅ΠΌΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Windows). ΠΠΎΡΡΠΎΠΌΡ, ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡΡ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΡΠ°ΠΊΠΆΠ΅, ΠΊΠ°ΠΊ ΡΡΠ° ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΡ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΠΈΠ· ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°. Π₯ΠΎΡΡ, ΡΠ΅ΠΆΠΈΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΠΈΠ»ΡΠ½ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½.
ΠΠΊΡΠΈΠ²Π½ΡΠΉ ΠΠ±ΡΠ΅ΠΊΡ ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ ΠΊΠ°ΠΊ ΠΊΠ°ΡΠΊΠ°Ρ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ ActiveObject. ΠΠΎΡΡΡΠΎΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°, ΠΊΠ°ΠΊ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π΄Π»Ρ ΡΠΈΡΡΡΡ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² InitThread, Run ΠΈ Flush (ΡΠ°ΠΊΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡΠ°).
class ActiveObject {
public:
ActiveObject();
virtual ~ActiveObject() {}
void Kill();
protected:
virtual void InitThread() = 0;
virtual void Run() = 0; virtual void FlushThread() = 0;
static DWORD WINAPI ThreadEntry(void *pArg);
int _isDying;
Thread _thread;
};
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΠΊΠ»Π°ΡΡΠ° ActiveObject ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠΉ ΠΏΠΎΡΠΎΠΊ, ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Ρ Π΅ΠΌΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΡ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ "this" Π½Π° ΡΠ΅Π±Ρ. ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΎΡΠΊΠ»ΡΡΠΈΡΡ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅, ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡΡΡΡΠ΅Π΅ ΠΎΠ± ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ "this" Π΄ΠΎ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΡ Π·Π½Π°Π΅ΠΌ, ΡΡΠΎ ΡΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠ°Π½ΡΡΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΏΠΎΡΠΎΠΊ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π² Π½Π΅Π°ΠΊΡΠΈΠ²Π½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ. ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° Π²ΡΠ·ΡΠ²Π°Π΅Ρ _thread.Resume() ΡΡΠΎΠ±Ρ Π°ΠΊΡΠΈΠ²ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΡΠΎΠΊ.
// The constructor of the derived class
// should call
// _thread.Resume ();
// at the end of construction
ActiveObject::ActiveObject() : _isDying (0),
#pragma warning(disable: 4355) // 'this' used before initialized
_thread(ThreadEntry, this)
#pragma warning(default: 4355)
{ }
ΠΠ΅ΡΠΎΠ΄ Kill Π²ΡΠ·ΡΠ²Π°Π΅Ρ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ FlushThread β ΡΡΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π»Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠ° ΠΈΠ· Π»ΡΠ±ΠΎΠ³ΠΎ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΠΈ Π΄Π°Π΅Ρ Π΅ΠΌΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π·Π°ΠΏΡΡΡΠΈΡΡ _isDying Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΠ»Π°ΠΆΠΊΠ°.
void ActiveObject::Kill() {
_isDying++;
FlushThread();
// Let's make sure it's gone
_thread.WaitForDeath();
}
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅ΠΌ ΠΊΠ°ΡΠΊΠ°Ρ Π΄Π»Ρ ΡΡΠ½ΠΊΡΠΈΠΈ ThreadEntry (ΡΡΠΎ β ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΠΊΠ»Π°ΡΡΠ° ActiveObject, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΡΠΎΠ³Π»Π°ΡΠ΅Π½ΠΈΠ΅ ΠΎ Π²ΡΠ·ΠΎΠ²Π°Ρ , ΡΡΠ΅Π±ΡΠ΅ΠΌΠΎΠ΅ API). ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠ΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠΌ ΠΏΠΎΡΠΎΠΊΠΎΠΌ. ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ, ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌΡΠΉ ΠΏΠΎΡΠΎΠΊΠΎΠΌ ΠΎΡ ΡΠΈΡΡΠ΅ΠΌΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π»ΠΈ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΏΠΎΡΠΎΠΊΠ° β ΡΡΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ "this" ΠΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΠ±ΡΠ΅ΠΊΡΠ°. API ΠΎΠΆΠΈΠ΄Π°Π΅Ρ void-ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π΄Π΅Π»Π°ΡΡ ΡΠ²Π½ΠΎΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ActiveObject. ΠΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ ΠΌΡ ΠΎΠ²Π»Π°Π΄Π΅Π²Π°Π΅ΠΌ ΠΠΊΡΠΈΠ²Π½ΡΠΌ ΠΠ±ΡΠ΅ΠΊΡΠΎΠΌ, ΠΌΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ ΡΠΈΡΡΡΠΉ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ InitThread, Π΄Π΅Π»Π°ΡΡ Π²ΡΠ΅ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΈΠ³ΠΎΡΠΎΠ²Π»Π΅Π½ΠΈΡ, Π° Π·Π°ΡΠ΅ΠΌ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠ°Π±ΠΎΡΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄ Run. Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΌΠ΅ΡΠΎΠ΄Π° Run ΠΎΡΡΠ°Π²Π»Π΅Π½Π° ΠΊΠ»ΠΈΠ΅Π½ΡΡ ΠΊΠ°ΡΠΊΠ°ΡΠ°.
DWORD WINAPI ActiveObject::ThreadEntry(void* pArg) {
ActiveObject* pActive = (ActiveObject*)pArg;
pActive->InitThread();
pActive->Run();
return 0;
}
ΠΠ±ΡΠ΅ΠΊΡ Thread β ΡΡΠΎ ΡΠΎΠ½ΠΊΠ°Ρ ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΡΡΠΈΡ API. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠ»Π°ΠΆΠΎΠΊ CREATE_SUSPENDED, ΠΊΠΎΡΠΎΡΡΠΉ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ, ΡΡΠΎ Π½ΠΈΡΡ Π½Π΅ Π½Π°ΡΠ½Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΏΡΠ΅ΠΆΠ΄Π΅, ΡΠ΅ΠΌ ΠΌΡ Π½Π΅ Π·Π°ΠΊΠΎΠ½ΡΠΈΠΌ ΠΊΠΎΠ½ΡΡΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ActiveObject.
class Thread {
public:
Thread(DWORD(WINAPI* pFun)(void* arg), void* pArg) {
_handle = CreateThread(
0, // Security attributes
0, // Stack size
pFun, pArg, CREATE_SUSPENDED, &_tid);
}
~Thread() {
CloseHandle(_handle);
}
void Resume() {