#if !defined CANVAS_HXX #define CANVAS_HXX #include class Canvas { public: Canvas():_hdc(0) {} HDC Handle() { return _hdc; } void Point ( int x, int y ) { SetPixel ( _hdc, x, y, 0L ); } void BluePoint ( int x, int y ) { SetPixel ( _hdc, x, y, RGB(0,0,255) ); } void RedPoint ( int x, int y ) { SetPixel ( _hdc, x, y, RGB(255,0,0) ); } void Line ( int x1, int y1, int x2, int y2 ) { MoveTo ( _hdc, x1, y1 ); LineTo ( _hdc, x2, y2 ); } void Circle(int x1, int y1, int r) { Ellipse(_hdc, x1-r, y1-r, x1+r, y1+r); } void Rect ( int x1, int y1, int x2, int y2 ) { Rectangle ( _hdc, x1, y1, x2, y2 ); } void Rect (RECT &r) { Rectangle (_hdc, r.left, r.top, r.right, r.bottom); } void Clear ( RECT& rect ) { FillRect ( _hdc, &rect, GetStockObject( WHITE_BRUSH )); } void Text ( int x, int y, char* buf, int cBuf ) { TextOut ( _hdc, x, y, buf, cBuf ); } void Char ( int x, int y, char c ) { TextOut ( _hdc, x, y, &c, 1 ); } void MapMode ( int mode ) { SetMapMode ( _hdc, mode ); } HDC DC() { return _hdc; } protected: void Init ( HDC hdc ) { _hdc = hdc; } HDC _hdc; }; class PaintCanvas: public Canvas { public: PaintCanvas ( HWND hwnd ): _hwnd(hwnd) { BeginPaint ( _hwnd, &_paint ); Init ( _paint.hdc ); SelectObject ( _hdc, GetStockObject (SYSTEM_FIXED_FONT) ); } ~PaintCanvas () { EndPaint(_hwnd, &_paint ); } HWND hwnd() {return _hwnd ;} protected: PAINTSTRUCT _paint; HWND _hwnd; }; // Device Context // Use for painting other than WM_PAINT class ScreenCanvas: public Canvas { public: ScreenCanvas ( HWND hwnd ): _hwnd(hwnd) { Init (GetDC ( hwnd )); SelectObject ( _hdc, GetStockObject (SYSTEM_FIXED_FONT) ); } ~ScreenCanvas () { ReleaseDC ( _hwnd, _hdc ); } void TextSize( int& cxChar, int& cyChar) { TEXTMETRIC tm; GetTextMetrics ( _hdc, &tm ); cxChar = tm.tmAveCharWidth; cyChar = tm.tmHeight + tm.tmExternalLeading; } HWND hwnd() {return _hwnd ;} protected: HWND _hwnd; }; //----------------------------------------------------------- class DotPen { public: //DotPen ( HDC hdc ) // : _hdc(hdc) //{ // make gaps transparent // _bkModeOld = SetBkMode (hdc, TRANSPARENT); // _hPen = CreatePen ( PS_DOT, 5, RGB(0, 255, 0) ); // _hPenOld = (HPEN) SelectObject (hdc, _hPen); //} DotPen ( HDC hdc, int r, int g, int b ) : _hdc(hdc) { // make gaps transparent //_bkModeOld = SetBkMode (hdc, TRANSPARENT); _hPen = CreatePen ( PS_DOT, 0, RGB(r,g,b) ); _hPenOld = (HPEN) SelectObject (hdc, _hPen); } ~DotPen () { SetBkMode ( _hdc, _bkModeOld ); SelectObject ( _hdc, _hPenOld ); DeleteObject ( _hPen ); } private: HDC _hdc; HPEN _hPen, _hPenOld; int _bkModeOld; }; //----------------------------------------------------------- class Pen { public: Pen ( HDC hdc, int style, int r, int g, int b ) : _hdc(hdc) { // make gaps transparent //_bkModeOld = SetBkMode (hdc, TRANSPARENT); _hPen = CreatePen ( style, 0, RGB(r,g,b) ); _hPenOld = (HPEN) SelectObject (hdc, _hPen); } ~Pen () { SetBkMode ( _hdc, _bkModeOld ); SelectObject ( _hdc, _hPenOld ); DeleteObject ( _hPen ); } private: HDC _hdc; HPEN _hPen, _hPenOld; int _bkModeOld; }; //----------------------------------------------------------- class Brusch { public: Brusch ( HDC hdc,int r, int g, int b ) : _hdc(hdc) { //_hBrusch = CreateBrush ( SOLID_BRUSH, 0, RGB(r, g, b) ); _hBrusch = CreateSolidBrush ( RGB(r, g, b) ); _hBruschOld = (HBRUSH) SelectObject (hdc, _hBrusch); } Brusch ( HDC hdc, COLORREF cr ) : _hdc(hdc) { _hBrusch = CreateSolidBrush ( cr ); _hBruschOld = (HBRUSH) SelectObject (hdc, _hBrusch); } ~Brusch () { SelectObject ( _hdc, _hBruschOld ); DeleteObject ( _hBrusch ); } private: HDC _hdc; HBRUSH _hBrusch, _hBruschOld; }; class HollowBrusch { public: HollowBrusch ( HDC hdc ) : _hdc(hdc) { // _hBrusch = GetStockObject( HOLLOW_BRUSH ); _hBrusch = GetStockObject( NULL_BRUSH ); _hBruschOld = (HBRUSH) SelectObject (hdc, _hBrusch); } ~HollowBrusch () { SelectObject ( _hdc, _hBruschOld ); DeleteObject ( _hBrusch ); } HBRUSH hBrusch(){ return _hBrusch; } private: HDC _hdc; HBRUSH _hBrusch, _hBruschOld; }; //--------------------------------------------------------- class DisplayContext { public: DisplayContext() { _hdc = CreateDC ("DISPLAY", NULL, NULL, NULL) ; } ~DisplayContext() { DeleteDC (_hdc) ; } HDC DC() { return _hdc; } private: HDC _hdc; }; class HdcRectSaver { public: HdcRectSaver(HDC hdc, int x, int y, int rWidth, int rHeight) : _hdc(hdc), _x(x), _y(y), _rWidth(rWidth), _rHeight(rHeight) { _hdcMem = CreateCompatibleDC (hdc) ; _hBitmap = CreateCompatibleBitmap ( hdc, rWidth, rHeight ) ; SelectObject (_hdcMem, _hBitmap) ; //BitBlt ( _hdcMem, x, y, rWidth, rHeight, hdc, 0, 0, SRCCOPY ) ; BitBlt ( _hdcMem, 0, 0, rWidth, rHeight, hdc, x, y, SRCCOPY ) ; } ~HdcRectSaver() { BitBlt (_hdc, _x, _y, _rWidth, _rHeight, _hdcMem, 0, 0, SRCCOPY) ; DeleteDC (_hdcMem) ; DeleteObject (_hBitmap) ; //MessageBeep(0); } HDC DC() { return _hdc; } private: int _x, _y, _rWidth, _rHeight ; HDC _hdc; HDC _hdcMem; HBITMAP _hBitmap; }; class Font { public: Font ( HDC hdc , int Height) : _hdc(hdc) { //char szFaceName[] = "Courier New" ; _hFont = CreateFont(Height, 0, 0, 0, 400, 0,0,0, ANSI_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS , DEFAULT_QUALITY, DEFAULT_PITCH, "Times New Roman") ; //"Courier New" _hFontOld = (HFONT) SelectObject (hdc, _hFont); } ~Font () { SelectObject ( _hdc, _hFontOld ); DeleteObject ( _hFont ); } private: HDC _hdc; HFONT _hFont, _hFontOld; }; //************************************************ #define BLOWERLEFT 0 #define BLOWERRIGHT 1 #define BUPPERLEFT 2 #define BUPPERRIGHT 3 #define BSVISIBLE 4 #define BSHIDEN 4 class Balloon { public: Balloon(HDC hdc): _hdc(hdc), _status(BSHIDEN) {} ShowBalloon(int x, int y, int stickLen, char * buf, int bStyle ) { if(_status == BSHIDEN ) { _x=x; _y=y; POINT p[3]; RECT r; r.left =0; r.top =0; r.bottom =1; r.right =1; DrawText(_hdc, buf, strlen(buf), (LPRECT)&r, DT_CALCRECT ) ; int bWidth = r.right+10; int bHeight = r.bottom; int x1, y1 ,x2, y2 ; switch( bStyle ) { case BLOWERRIGHT : p[0].x =x; p[0].y =y; p[1].x =x + stickLen; p[1].y =y + stickLen - 5; p[2].x =x + stickLen-5; p[2].y =y + stickLen; p[3].x =x; p[3].y =y; x1 = x + stickLen-10 ; y1 = y + stickLen-10 ; x2 = x + stickLen-10 + bWidth ; y2 = y + stickLen-10 + bHeight ; break; case BUPPERLEFT : p[0].x =x; p[0].y =y; p[1].x =x - stickLen; p[1].y =y - stickLen + 5 ; p[2].x =x - stickLen + 5 ; p[2].y =y - stickLen; p[3].x =x; p[3].y =y; x1 = x - stickLen+10 ; y1 = y - stickLen +10 ; x2 = x - stickLen+10 - bWidth ; y2 = y - stickLen +10 - bHeight ; break; case BLOWERLEFT : p[0].x =x; p[0].y =y; p[1].x =x - stickLen; p[1].y =y + stickLen - 5 ; p[2].x =x - stickLen + 5 ; p[2].y =y + stickLen; p[3].x =x; p[3].y =y; x1 = x - stickLen+10 ; y1 = y + stickLen -10 ; x2 = x - stickLen+10 - bWidth ; y2 = y + stickLen -10 + bHeight ; break; case BUPPERRIGHT : p[0].x = x; p[0].y =y; p[1].x = x + stickLen ; p[1].y =y - stickLen + 5 ; p[2].x = x + stickLen - 5 ; p[2].y =y - stickLen; p[3].x = x; p[3].y =y; x1 = x + stickLen-10 ; y1 = y - stickLen + 10 ; x2 = x + stickLen-10 + bWidth ; y2 = y - stickLen + 10 - bHeight ; break; } //create balloon region HRGN hrgn0 = CreatePolygonRgn((LPPOINT)p, 4, ALTERNATE); HRGN hrgn1 = CreateRoundRectRgn(x1, y1, x2, y2,10,10); GetRgnBox(hrgn1, (LPRECT) &_TextRect) ; _hrgn = CreateRectRgn(0, 0, 1, 1); CombineRgn(_hrgn, hrgn1 , hrgn0, RGN_OR ); DeleteObject(hrgn0); DeleteObject(hrgn1); // store curent part of screen in _hdcMem GetRgnBox(_hrgn, (LPRECT) &_BalloonBox) ; _rWidth = _BalloonBox.right - _BalloonBox.left+10; _rHeight = _BalloonBox.bottom - _BalloonBox.top+10; _hdcMem = CreateCompatibleDC (_hdc) ; _rx = _x - _rWidth; _ry = _y - _rHeight; _refreshWidth = 2*_rWidth; _refreshHeight = 2*_rHeight; HBITMAP hBitmap = CreateCompatibleBitmap ( _hdc, _refreshWidth, _refreshHeight ) ; SelectObject (_hdcMem, hBitmap) ; BitBlt ( _hdcMem, 0, 0, _refreshWidth , _refreshHeight, _hdc, _rx , _ry, SRCCOPY ) ; DeleteObject (hBitmap) ; //paint balloon PaintRgn(_hdc, _hrgn); //draw balloon text with transparent gaps int bkModeOld = SetBkMode (_hdc, TRANSPARENT); DrawText(_hdc, buf, strlen(buf), (LPRECT)&_TextRect, DT_CENTER ) ; SetBkMode ( _hdc, bkModeOld ); _status == BSVISIBLE; } //end of status if() } HideBalloon() { if(_status == BSVISIBLE ) { // restore previous part of screen BitBlt (_hdc, _rx , _ry , _refreshWidth, _refreshHeight, _hdcMem, 0, 0, SRCCOPY) ; _status == BSHIDEN; } } ~Balloon() { DeleteObject(_hrgn); DeleteDC (_hdcMem) ; } HDC DC() { return _hdc; } private: int _rx, _ry, _status; HDC _hdc; HRGN _hrgn; RECT _TextRect; RECT _BalloonBox; int _x, _y, _rWidth, _rHeight, _refreshWidth, _refreshHeight; HDC _hdcMem; }; //balloons usage //Create yellow balloon, with text in bufer buf //s.DC() - ScreenCanvas device context //Font fff( s.DC(), 15 ); //Brusch b2( s.DC(),255, 255, 0 ); //char buf[100]="electrode (1,2)\n1234e-11"; //lstrcat(buf,""); //Balloon bulb(s.DC()) ; //bulb.ShowBalloon(pt.x, pt.y, 30, buf, BLOWERRIGHT ); //or //bulb.ShowBalloon(pt.x, pt.y, 30, buf, BUPPERRIGHT ); #endif