void Bezier::DrawBezier (HDC hdc, POINT points[]) { PolyBezier (hdc, points, 4) ; MoveToEx (hdc, points[0].x, points[0].y, NULL) ; LineTo (hdc, points[1].x, points[1].y) ; MoveToEx (hdc, points[2].x, points[2].y, NULL) ; LineTo (hdc, points[3].x, points[3].y) ; }
void DrawBezier (HDC hdc, POINT apt[]) { PolyBezier (hdc, apt, 4); MoveToEx (hdc, apt[0].x, apt[0].y, NULL); LineTo (hdc, apt[1].x, apt[1].y); MoveToEx (hdc, apt[2].x, apt[2].y, NULL); LineTo (hdc, apt[3].x, apt[3].y); }
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; POINT points[4] = { 20, 40, 320, 200, 330, 110, 450, 40 }; switch(msg) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); PolyBezier(hdc, points, 4); EndPaint(hwnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProcW(hwnd, msg, wParam, lParam); }
PHP_METHOD(WinGdiPath, beizer) { wingdi_devicecontext_object *dc_obj; wingdi_path_object *path_obj; zval ***parameters, **x, **y; POINT *points = NULL; DWORD points_total = 0; int param_count, i; WINGDI_ERROR_HANDLING(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", ¶meters, ¶m_count) == FAILURE) return; WINGDI_RESTORE_ERRORS(); path_obj = zend_object_store_get_object(getThis() TSRMLS_CC); dc_obj = zend_object_store_get_object(path_obj->device_context TSRMLS_CC); points = emalloc(param_count * sizeof(POINT)); for (i = 0; i < param_count; i++) { // We expect only arrays if (Z_TYPE_PP(parameters[i]) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "expected array for parameter %d, got %s", i + 1, zend_zval_type_name(*(parameters[i]))); goto CLEANUP; } else { // We want 2 elements if (zend_hash_num_elements(Z_ARRVAL_PP(parameters[i])) != 2) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "expected 2 elements for array at parameter %d, got %d", i + 1, zend_hash_num_elements(Z_ARRVAL_PP(parameters[i]))); goto CLEANUP; } else { zend_hash_index_find(Z_ARRVAL_PP(parameters[i]), 0, (void **)&x); zend_hash_index_find(Z_ARRVAL_PP(parameters[i]), 1, (void **)&y); if (Z_TYPE_PP(x) != IS_LONG) convert_to_long(*x); if (Z_TYPE_PP(y) != IS_LONG) convert_to_long(*y); points[i].x = Z_LVAL_PP(x); points[i].y = Z_LVAL_PP(y); points_total++; } } } RETVAL_BOOL(PolyBezier(dc_obj->hdc, points, points_total)); CLEANUP: efree(points); }
void Bezier(HDC hdc, POINT p1, POINT p2, POINT p3, POINT p4, COLORREF color, int thickness) { HPEN oldPen; POINT fourPoints[4]; fourPoints[0] = p1; fourPoints[1] = p2; fourPoints[2] = p3; fourPoints[3] = p4; oldPen = SelectObject(hdc, CreatePen(PS_SOLID, thickness, color)); PolyBezier(hdc, fourPoints, 4); DeleteObject(SelectObject(hdc, oldPen)); }
BOOL nulldrv_PolyBezierTo( PHYSDEV dev, const POINT *points, DWORD count ) { BOOL ret = FALSE; POINT *pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (count + 1) ); if (pts) { GetCurrentPositionEx( dev->hdc, &pts[0] ); memcpy( pts + 1, points, sizeof(POINT) * count ); ret = PolyBezier( dev->hdc, pts, count + 1 ); HeapFree( GetProcessHeap(), 0, pts ); } return ret; }
BOOL nulldrv_PolyBezierTo( PHYSDEV dev, const POINT *points, DWORD count ) { DC *dc = get_nulldrv_dc( dev ); BOOL ret = FALSE; POINT *pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (count + 1) ); if (pts) { pts[0] = dc->cur_pos; memcpy( pts + 1, points, sizeof(POINT) * count ); ret = PolyBezier( dev->hdc, pts, count + 1 ); HeapFree( GetProcessHeap(), 0, pts ); } return ret; }
bool GiCanvasGdi::rawBeziers(const GiContext* ctx, const Point2d* pxs, int count) { HDC hdc = m_draw->getDrawDC(); KGDIObject pen (hdc, m_draw->createPen(ctx), false); bool ret = false; if (count > 0) { std::vector<POINT> pts; pts.resize(count); for (int i = 0; i < count; i++) pxs[i].get(pts[i].x, pts[i].y); ret = !!PolyBezier(hdc, &pts.front(), count); } return ret; }
// Drawing a full ellipse using 4 Bezier curves BOOL EllipseToBezier(HDC hDC, int left, int top, int right, int bottom) { const double M = 0.55228474983; POINT P[13]; int dx = (int) ((right - left) * (1-M) / 2); int dy = (int) ((bottom - top) * (1-M) / 2); P[ 0].x = right; // . . . . . P[ 0].y = (top+bottom)/2; // 4 3 2 P[ 1].x = right; // P[ 1].y = top + dy; // 5 1 P[ 2].x = right - dx; // P[ 2].y = top; // 6 0,12 P[ 3].x = (left+right)/2; // P[ 3].y = top; // 7 11 // P[ 4].x = left + dx; // 8 9 10 P[ 4].y = top; P[ 5].x = left; P[ 5].y = top + dy; P[ 6].x = left; P[ 6].y = (top+bottom)/2; P[ 7].x = left; P[ 7].y = bottom - dy; P[ 8].x = left + dx; P[ 8].y = bottom; P[ 9].x = (left+right)/2; P[ 9].y = bottom; P[10].x = right - dx; P[10].y = bottom; P[11].x = right; P[11].y = bottom - dy; P[12].x = right; P[12].y = (top+bottom)/2; return PolyBezier(hDC, P, 13); }
void DisasmView_DrawJump(HDC hdc, int yFrom, int delta, int x, int cyLine) { int dist = abs(delta); if (dist < 2) dist = 2; if (dist > 20) dist = 16; int yTo = yFrom + delta * cyLine; yFrom += cyLine / 2; HGDIOBJ oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, COLOR_JUMP)); POINT points[4]; points[0].x = x; points[0].y = yFrom; points[1].x = x + dist * 4; points[1].y = yFrom; points[2].x = x + dist * 12; points[2].y = yTo; points[3].x = x; points[3].y = yTo; PolyBezier(hdc, points, 4); MoveToEx(hdc, x - 4, points[3].y, NULL); LineTo(hdc, x + 4, yTo - 1); MoveToEx(hdc, x - 4, points[3].y, NULL); LineTo(hdc, x + 4, yTo + 1); SelectObject(hdc, oldPen); }
void Demo_LineCurve(HDC hDC, const RECT * rcPaint, int width, int height) { // ROP2 KLogFont logfont(- 10 * ONEINCH / 72, "Tahoma"); KGDIObject font(hDC, logfont.CreateFont()); for (int c=0; c<20; c++) { RECT rect = { c*200+400, 300, c*200+580, 4000 }; HBRUSH hBrush = CreateSolidBrush(PALETTEINDEX(c)); FillRect(hDC, & rect, hBrush); DeleteObject(hBrush); } { KGDIObject redbrush(hDC, CreateSolidBrush(RGB(0xFF, 0, 0))); SelectObject(hDC, GetStockObject(NULL_PEN)); SetTextAlign(hDC, TA_TOP | TA_LEFT); for (int r=R2_BLACK; r<=R2_WHITE; r++) { SetROP2(hDC, r); TextOut(hDC, 4400, r*220+200, R2_Names[r-R2_BLACK], _tcslen(R2_Names[r-R2_BLACK])); Rectangle(hDC, 300, r*220+200, 4300, r*220+400); } SetROP2(hDC, R2_COPYPEN); } { KPen Red (PS_DOT, 0, RGB(0xFF, 0, 0)); KPen Blue(PS_SOLID, ONEINCH/36, RGB(0, 0, 0xFF)); for (int z=0; z<=2000; z+=400) { int x = 400, y = 6400; POINT p[4] = { x, y, x+ 400, y-z, x+800, y-z, x+1200, y }; x+= 1300; POINT q[4] = { x, y, x+ 400, y-z, x+800, y+z, x+1200, y }; x+= 1400; POINT r[4] = { x, y, x+1500, y-z, x- 200, y-z, x+1300, y }; x+= 1800; POINT s[4] = { x, y, x+1500, y-z, x- 200, y+z, x+1300, y }; x+= 1600; POINT t[4] = { x+600, y, x, y-z, x+1300, y-z, x+600, y }; Red.Select(hDC); Polyline(hDC, p, 4); Polyline(hDC, q, 4); Polyline(hDC, r, 4); Polyline(hDC, s, 4); Polyline(hDC, t, 4); Red.UnSelect(); Blue.Select(hDC); PolyBezier(hDC, p, 4); PolyBezier(hDC, q, 4); PolyBezier(hDC, r, 4); PolyBezier(hDC, s, 4); PolyBezier(hDC, t, 4); Blue.UnSelect(); } } }
void polyBezier(const POINT *lppt,int cPoints) { PolyBezier(g_hmemdc,lppt,cPoints); }
VOID PolyDrawBez(HWND hWnd) { //PPOLYDATA ppd; //LPBEZBUFFER lpBez,lpCurr,lpPrev; int idx,x,y; RECT rect; HDC hDC; HPEN hPen; static COLORREF crColor[] = {0x000000FF,0x0000FF00,0x00FF0000,0x0000FFFF, 0x00FF00FF,0x00FFFF00,0x00FFFFFF,0x00000080, 0x00008000,0x00800000,0x00008080,0x00800080, 0x00808000,0x00808080,0x000000FF,0x0000FF00, 0x00FF0000,0x0000FFFF,0x00FF00FF,0x00FFFF00}; //if(ppd = (PPOLYDATA)HeapAlloc(GetProcessHeap(),HEAP_NO_SERIALIZE,sizeof(POLYDATA))) // { // if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer)) // { if(hDC = GetDC(hWnd)) { GetClientRect(hWnd,&rect); lpPrev = lpBez+ppd->nBezCurr; ppd->nBezCurr += 1; if(ppd->nBezCurr >= ppd->nBezTotal) { ppd->nBezCurr = 0; ppd->nColor = (++ppd->nColor % 20); } lpCurr = lpBez+ppd->nBezCurr; if(lpCurr->pPts[0].x != -1) { hPen = SelectObject(hDC,GetStockObject(WHITE_PEN)); //#if defined(_WIN32) && defined(WIN32) PolyBezier(hDC,lpCurr->pPts,BEZ_PTS); //#else // Polyline(hDC,lpCurr->pPts,BEZ_PTS); //#endif SelectObject(hDC,hPen); } for(idx=0; idx < BEZ_PTS; idx++) { x = lpPrev->pPts[idx].x; y = lpPrev->pPts[idx].y; x += ppd->pVel[idx].x; y += ppd->pVel[idx].y; if(x >= rect.right) { x = rect.right - ((x - rect.right)+1); ppd->pVel[idx].x = -PolyNewVel(idx); } if(x <= rect.left) { x = rect.left + ((rect.left - x)+1); ppd->pVel[idx].x = PolyNewVel(idx); } if(y >= rect.bottom) { y = rect.bottom - ((y - rect.bottom)+1); ppd->pVel[idx].y = -PolyNewVel(idx); } if(y <= rect.top) { y = rect.top + ((rect.top - y)+1); ppd->pVel[idx].y = PolyNewVel(idx); } lpCurr->pPts[idx].x = x; lpCurr->pPts[idx].y = y; } hPen = SelectObject(hDC,CreatePen(PS_SOLID,1,crColor[ppd->nColor])); //#if defined(_WIN32) && defined(WIN32) PolyBezier(hDC,lpCurr->pPts,BEZ_PTS); //#else // Polyline(hDC,lpCurr->pPts,BEZ_PTS); //#endif DeleteObject(SelectObject(hDC,hPen)); //#if defined(_WIN32) && defined(WIN32) SetROP2(hDC,R2_COPYPEN); //#endif ReleaseDC(hWnd,hDC); // } // GlobalUnlock(ppd->hBezBuffer); //} //UnlockWindowInfo(hWnd); } }
VOID PolyRedraw(HWND hWnd) { //PPOLYDATA ppd; //LPBEZBUFFER lpBez,lpCurr; HDC hDC; int i,j; RECT rect; //if(ppd = (PPOLYDATA)LockWindowInfo(hWnd)) //{ // if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer)) // { if(hDC = GetDC(hWnd)) { /* ** Save the current bezier. Set the first bezier in the ** array to that curve, and use it as a basis for the next ** series. */ lpCurr = lpBez+ppd->nBezCurr; *lpBez = *lpCurr; ppd->nBezCurr = 0; /* ** Clean the curves (all but the first curve). */ for(j=1; j < ppd->nBezTotal; j++) { for(i=0; i < BEZ_PTS; i++) { (lpBez+j)->pPts[i].x = -1; (lpBez+j)->pPts[i].y = 0; } } /* ** Clear the display. */ GetClientRect(hWnd,&rect); BitBlt(hDC,0,0,rect.right, rect.bottom,(HDC)0,0,0,WHITENESS); /* ** Draw the first curve in the bezier array. */ //#if defined(_WIN32) && defined(WIN32) PolyBezier(hDC,lpBez->pPts,BEZ_PTS); //#else // Polyline(hDC,lpBez->pPts,BEZ_PTS); //#endif ReleaseDC(hWnd,hDC); // } // GlobalUnlock(ppd->hBezBuffer); //} //UnlockWindowInfo(hWnd); } return; }
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hwndEraserWeight; static HWND hwndStrokeWeight; static HWND hwndPenTool; static HWND hwndLineTool; static HWND hwndPolygonTool; static HWND hwndEllipseTool; static HWND hwndBezierTool; static HWND hwndEraserTool; static HWND hwndFillCheck; static POINT pen; static BOOL firstLine; static POINT newLine; static BOOL firstPolygon; static RECT newPolygon; static BOOL firstEllipse; static RECT newEllipse; static BOOL firstBezier; static BOOL secondBezier; static BOOL thirdBezier; static POINT pointsforBezier[4]; static HRGN lastRegion; static BOOL regionDeleted; int xMouse, yMouse; static RECT drawingArea = {15, 180, 580, 640}; RECT rectRED = {255, 100, 375, 115}; RECT rectGREEN = {255, 120, 375, 135}; RECT rectBLUE = {255, 140, 375, 155}; RECT rectTemp; HDC hdc = GetDC(hwnd); COLORREF strokeRGB; int strokeWeight; COLORREF fillRGB; HBRUSH fillBrush; PAINTSTRUCT ps; HPEN strokePen; POINT point; RECT rect; HBRUSH hBrush; int xFillPreview =240 ; int yFillPreview = 50; int xStrokePreview = 320; int yStrokePreview = 50; UINT fillRED = 255; UINT fillGREEN = 255; UINT fillBLUE = 255; UINT strokeRED = 0; UINT strokeGREEN = 0; UINT strokeBLUE = 0; HDC hdcMem; BITMAP bitmap; HBITMAP hbmpimage = NULL; hbmpimage = (HBITMAP)LoadImage(hInstance, "aesthetic1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); GetObject(hbmpimage, sizeof(bitmap), &bitmap); switch(message) { case WM_CREATE: CreateWindowEx( 0, "Button", "Tools", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 5, 5, 100, 160, hwnd, 0, hInstance, NULL); CreateWindowEx( 0, "Button", "Style", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 520, 5, 135, 120, hwnd, 0, hInstance, NULL); CreateWindowEx( 0, "Button", "Color", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 220, 5, 180, 160, hwnd, 0, hInstance, NULL); CreateWindowEx( 0, "Static", "Fill", WS_VISIBLE | WS_CHILD | SS_CENTER, 240, 25, 45, 20, hwnd, (HMENU)0, hInstance, NULL); CreateWindowEx( 0, "Static", "Stroke", WS_VISIBLE | WS_CHILD | SS_CENTER, 320, 25, 45, 20, hwnd, (HMENU)0, hInstance, NULL); CreateWindowEx( 0, "Static", "R", WS_VISIBLE | WS_CHILD | SS_LEFT, 240, 100, 10, 15, hwnd, (HMENU)0, hInstance, NULL); CreateWindowEx( 0, "Static", "G", WS_VISIBLE | WS_CHILD | SS_LEFT, 240, 120, 10, 15, hwnd, (HMENU)0, hInstance, NULL); CreateWindowEx( 0, "Static", "B", WS_VISIBLE | WS_CHILD | SS_LEFT, 240, 140, 10, 15, hwnd, (HMENU)0, hInstance, NULL); hwndPenTool = CreateWindowEx( 0, "Button", "Pen", WS_VISIBLE | WS_CHILD | WS_GROUP | BS_AUTORADIOBUTTON, 15, 30, 80, 18, hwnd, (HMENU)IDB_PEN, hInstance, NULL); Button_SetCheck(hwndPenTool, BST_CHECKED); hwndLineTool = CreateWindowEx( 0, "Button", "Line", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 15, 55, 80, 18, hwnd, (HMENU)IDB_LINE, hInstance, NULL); hwndPolygonTool = CreateWindowEx( 0, "Button", "Polygon", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 15, 80, 80, 18, hwnd, (HMENU)IDB_POLYGON, hInstance, NULL); hwndEllipseTool = CreateWindowEx( 0, "Button", "Ellipse", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 15, 105, 80, 18, hwnd, (HMENU)IDB_ELLIPSE, hInstance, NULL); hwndBezierTool = CreateWindowEx( 0, "Button", "Bezier", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 15, 130, 80, 18, hwnd, (HMENU)IDB_BEZIER, hInstance, NULL); hwndFillCheck = CreateWindowEx( 0, "Button", "Fill", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, 530, 30, 80, 18, hwnd, (HMENU)0, hInstance, NULL); CreateWindowEx( 0, "Static", "Stroke", WS_VISIBLE | WS_CHILD, 530, 60, 80, 20, hwnd, (HMENU)0, hInstance, NULL); hwndStrokeWeight = CreateWindowEx( 0, "Edit", "1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 620, 60, 20, 20, hwnd, (HMENU)0, hInstance, NULL); hwndEraserTool = CreateWindowEx( 0, "Button", "Eraser", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 530, 90, 80, 20, hwnd, (HMENU)IDB_ERASER, hInstance, NULL); hwndEraserWeight = CreateWindowEx( 0, "Edit", "1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 620, 90, 20, 20, hwnd, (HMENU)0, hInstance, NULL); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { default: DefWindowProc(hwnd, WM_COMMAND, wParam, lParam); break; } return 0; case WM_LBUTTONDOWN: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if((xMouse > rectRED.left)&&(xMouse <= rectRED.right)) { strokeRGB = GetPixel(hdc, xStrokePreview + 20, yStrokePreview + 20); if((yMouse > rectRED.top)&&(yMouse <= rectRED.bottom)) { strokeRED = (xMouse - rectRED.left) * 255 / (rectRED.right - rectRED.left); strokeGREEN = GetGValue(strokeRGB); strokeBLUE = GetBValue(strokeRGB); updateColorPreview(hdc, RGB(strokeRED, strokeGREEN, strokeBLUE), xStrokePreview, yStrokePreview); } else if((yMouse > rectGREEN.top)&&(yMouse <= rectGREEN.bottom)) { strokeRED = GetRValue(strokeRGB); strokeGREEN = (xMouse - rectGREEN.left) * 255 / (rectGREEN.right - rectGREEN.left); strokeBLUE = GetBValue(strokeRGB); updateColorPreview(hdc, RGB(strokeRED, strokeGREEN, strokeBLUE), xStrokePreview, yStrokePreview); } else if((yMouse > rectBLUE.top)&&(yMouse <= rectBLUE.bottom)) { strokeRED = GetRValue(strokeRGB); strokeGREEN = GetGValue(strokeRGB); strokeBLUE = (xMouse - rectBLUE.left) * 255 / (rectBLUE.right - rectBLUE.left); updateColorPreview(hdc, RGB(strokeRED, strokeGREEN, strokeBLUE), xStrokePreview, yStrokePreview); } return 0; } if((xMouse > drawingArea.left)&&(xMouse < drawingArea.right)&&(yMouse > drawingArea.top)&&(yMouse < drawingArea.bottom)) { strokeWeight = getWeight(hwndStrokeWeight); point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); xMouse = point.x; yMouse = point.y; if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndPenTool) == BST_CHECKED)) { pen.x = xMouse; pen.y = yMouse; } if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndLineTool) == BST_CHECKED)) { newLine.x = xMouse; newLine.y = yMouse; firstLine = true; } if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndPolygonTool) == BST_CHECKED)) { newPolygon.left = xMouse; newPolygon.top = yMouse; firstPolygon = true; } if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndEllipseTool) == BST_CHECKED)) { newEllipse.left = xMouse; newEllipse.top = yMouse; firstEllipse = true; } if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndBezierTool) == BST_CHECKED)) { pointsforBezier[0] = point; firstBezier = true; secondBezier = false; thirdBezier = false; } } return 0; case WM_LBUTTONUP: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); strokeRGB = GetPixel(hdc, xStrokePreview + 20, yStrokePreview + 20); fillRGB = GetPixel(hdc, xFillPreview + 20, yFillPreview + 20); strokeWeight = getWeight(hwndStrokeWeight); if(firstLine) { point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); xMouse = point.x; yMouse = point.y; strokePen = CreatePen(PS_SOLID, strokeWeight, strokeRGB); SelectObject(hdc, strokePen); MoveToEx(hdc, xMouse, yMouse, NULL); LineTo(hdc, newLine.x, newLine.y); DeleteObject(strokePen); firstLine = false; } if(firstPolygon) { point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); newPolygon.right = point.x; newPolygon.bottom = point.y; strokePen = CreatePen(PS_SOLID, strokeWeight, strokeRGB); fillBrush = (Button_GetCheck(hwndFillCheck) == BST_CHECKED)? CreateSolidBrush(fillRGB) : (HBRUSH)GetStockObject(NULL_BRUSH); SelectObject(hdc, strokePen); SelectObject(hdc, fillBrush); Rectangle(hdc, newPolygon.left, newPolygon.top, newPolygon.right, newPolygon.bottom); DeleteObject(strokePen); DeleteObject(fillBrush); lastRegion = getLastRectRegion(newPolygon, strokeWeight, ®ionDeleted); firstPolygon = false; } if(firstEllipse) { point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); newEllipse.right = point.x; newEllipse.bottom = point.y; strokePen = CreatePen(PS_SOLID, strokeWeight, strokeRGB); fillBrush = (Button_GetCheck(hwndFillCheck) == BST_CHECKED)? CreateSolidBrush(fillRGB) : (HBRUSH)GetStockObject(NULL_BRUSH); SelectObject(hdc, strokePen); SelectObject(hdc, fillBrush); Ellipse(hdc, newEllipse.left, newEllipse.top, newEllipse.right, newEllipse.bottom); DeleteObject(strokePen); DeleteObject(fillBrush); lastRegion = getLastEllipticRegion(newEllipse, strokeWeight, ®ionDeleted); firstEllipse = false; } if(firstBezier) { point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); pointsforBezier[1] = point; firstBezier = false; secondBezier = true; thirdBezier = false; } return 0; case WM_RBUTTONDOWN: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if((xMouse > rectRED.left)&&(xMouse <= rectRED.right)) { fillRGB = GetPixel(hdc, xFillPreview + 20, yFillPreview + 20); if((yMouse > rectRED.top)&&(yMouse <= rectRED.bottom)) { fillRED = (xMouse - rectRED.left) * 255 / (rectRED.right - rectRED.left); fillGREEN = GetGValue(fillRGB); fillBLUE = GetBValue(fillRGB); updateColorPreview(hdc, RGB(fillRED, fillGREEN, fillBLUE), xFillPreview, yFillPreview); } else if((yMouse > rectGREEN.top)&&(yMouse <= rectGREEN.bottom)) { fillRED = GetRValue(fillRGB); fillGREEN = (xMouse - rectGREEN.left) * 255 / (rectGREEN.right - rectGREEN.left); fillBLUE = GetBValue(fillRGB); updateColorPreview(hdc, RGB(fillRED, fillGREEN, fillBLUE), xFillPreview, yFillPreview); } else if((yMouse > rectBLUE.top)&&(yMouse <= rectBLUE.bottom)) { fillRED = GetRValue(fillRGB); fillGREEN = GetGValue(fillRGB); fillBLUE = (xMouse - rectBLUE.left) * 255 / (rectBLUE.right - rectBLUE.left); updateColorPreview(hdc, RGB(fillRED, fillGREEN, fillBLUE), xFillPreview, yFillPreview); } return 0; } if((xMouse > drawingArea.left)&&(xMouse < drawingArea.right)&&(yMouse > drawingArea.top)&&(yMouse < drawingArea.bottom)) { strokeWeight = getWeight(hwndStrokeWeight); point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); xMouse = point.x; yMouse = point.y; if((wParam == MK_RBUTTON)&&(Button_GetCheck(hwndBezierTool) == BST_CHECKED)&&(secondBezier)) { pointsforBezier[2] = point; firstBezier = false; secondBezier = false; thirdBezier = true; } } if(regionDeleted) { InvalidateRgn(hwnd, lastRegion, TRUE); DeleteObject(lastRegion); regionDeleted = false; } return 0; case WM_RBUTTONUP: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); strokeRGB = GetPixel(hdc, xStrokePreview + 20, yStrokePreview + 20); fillRGB = GetPixel(hdc, xFillPreview + 20, yFillPreview + 20); strokeWeight = getWeight(hwndStrokeWeight); point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); xMouse = point.x; yMouse = point.y; if(thirdBezier) { pointsforBezier[3] = point; strokePen = CreatePen(PS_SOLID, strokeWeight, strokeRGB); SelectObject(hdc, strokePen); PolyBezier(hdc, pointsforBezier, 4); DeleteObject(strokePen); firstBezier = false; secondBezier = false; thirdBezier = false; } return 0; case WM_MOUSEMOVE: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if((xMouse > drawingArea.left)&&(xMouse < drawingArea.right) &&(yMouse > drawingArea.top)&&(yMouse < drawingArea.bottom)) { strokeRGB = GetPixel(hdc, xStrokePreview + 20, yStrokePreview + 20); fillRGB = GetPixel(hdc, xStrokePreview + 20, yStrokePreview + 20); if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndPenTool) == BST_CHECKED)) { strokePen = CreatePen(PS_SOLID, 1, strokeRGB); SelectObject(hdc, strokePen); MoveToEx(hdc, xMouse, yMouse, NULL); LineTo(hdc, pen.x, pen.y); DeleteObject(strokePen); pen.x = xMouse; pen.y = yMouse; } if((wParam == MK_LBUTTON)&&(Button_GetCheck(hwndEraserTool) == BST_CHECKED)) { strokeWeight = getWeight(hwndEraserWeight); point = drawingLimits(xMouse, yMouse, drawingArea, strokeWeight); xMouse = point.x; yMouse = point.y; rect.left = point.x - (strokeWeight/2); rect.right = point.x + (strokeWeight/2); rect.top = point.y - (strokeWeight/2); rect.bottom = point.y + (strokeWeight/2); InvalidateRect(hwnd, &rect, FALSE); SendMessage(hwnd, WM_PAINT, 0, 0); ValidateRect(hwnd, &rect); } } return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); updateColorPreview(hdc, RGB(255, 255, 255), xFillPreview, yFillPreview); updateColorPreview(hdc, RGB(0, 0, 0), xStrokePreview, yStrokePreview); hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hbmpimage); BitBlt(hdc, 600, 40, 280, 600, hdcMem, 0, 0, SRCCOPY); DeleteDC(hdcMem); rectTemp.top = rectRED.top; rectTemp.bottom = rectRED.bottom; for(int i = 0; i < (rectRED.right - rectRED.left); i++) { int r; r = i * 255 / (rectRED.right - rectRED.left); rectTemp.left = rectRED.left + i; rectTemp.right = rectRED.left + i + 1; hBrush = CreateSolidBrush(RGB(r, 0, 0)); FillRect(hdc, &rectTemp, hBrush); DeleteObject(hBrush); } rectTemp.top = rectGREEN.top; rectTemp.bottom = rectGREEN.bottom; for(int i = 0; i < (rectGREEN.right - rectGREEN.left); i++) { int g; g = i * 255 / (rectGREEN.right - rectGREEN.left); rectTemp.left = rectGREEN.left + i; rectTemp.right = rectGREEN.left + i + 1; hBrush = CreateSolidBrush(RGB(0, g, 0)); FillRect(hdc, &rectTemp, hBrush); DeleteObject(hBrush); } rectTemp.top = rectBLUE.top; rectTemp.bottom = rectBLUE.bottom; for(int i = 0; i < (rectBLUE.right - rectBLUE.left); i++) { int b; b = i * 255 / (rectBLUE.right - rectBLUE.left); rectTemp.left = rectBLUE.left + i; rectTemp.right = rectBLUE.left + i + 1; hBrush = CreateSolidBrush(RGB(0, 0, b)); FillRect(hdc, &rectTemp, hBrush); DeleteObject(hBrush); } SelectObject(hdc, CreatePen(PS_SOLID, 1, RGB(0,0,0))); SelectObject(hdc, (HBRUSH)GetStockObject(WHITE_BRUSH)); Rectangle(hdc, drawingArea.left, drawingArea.top, drawingArea.right, drawingArea.bottom); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage (0); return 0; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hPencil, hLine, hBezier, hRectangle, hEllipse, hEraser, hFill, hBorderW, hEraserW, hClear; RECT rect ; PAINTSTRUCT ps; HDC hdc = GetDC(hwnd); int screenW, screenH; int xMouse, yMouse; int xFillPreview = 200; int yFillPreview = 515; int xStrokePreview = 310; int yStrokePreview = 515; HDC hdcMem; BITMAP bitmap; HBITMAP hbit; static RECT drawingArea = {25, 55, 750, 500}; static RECT fillColorRect = {xFillPreview, yFillPreview, xFillPreview + 25, yFillPreview + 20}; static RECT borderColorRect = {xStrokePreview, yStrokePreview, xStrokePreview + 25, yStrokePreview + 20}; static RECT tempRect; HBRUSH hBrush; static POINT pointPen; POINT point; HPEN linePen; int width; static BOOL lineStarted, rectangleStarted, ellipseStarted; static RECT rectangle, ellipse; static int bezierStage = 0; static POINT line; static POINT bezierPoints[4]; HPEN borderPen; HBRUSH fillBrush; switch (message) { case WM_CREATE: hImageBttn = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_PENCIL)); screenW = GetSystemMetrics(SM_CXSCREEN); screenH = GetSystemMetrics(SM_CYSCREEN); GetWindowRect(hwnd, &rect); SetWindowPos(hwnd, 0, (screenW - rect.right)/2, (screenH - rect.bottom)/2, 0, 0, SWP_NOZORDER|SWP_NOSIZE); hPencil = CreateWindowEx( 0, "Button", NULL, WS_VISIBLE| WS_CHILD|BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_BITMAP , 25, 15, 32, 32, hwnd, (HMENU)IDB_pencil, hInst, NULL); SendMessage(hPencil, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hImageBttn); hImageBttn = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_LINE)); hLine = CreateWindowEx( 0, "Button", NULL, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_BITMAP, 65, 15, 32, 32, hwnd, (HMENU)IDB_line, hInst, NULL); SendMessage(hLine, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hImageBttn); hImageBttn = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_BEZIER)); hBezier = CreateWindowEx( 0, "Button", NULL, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_BITMAP, 105, 15, 32, 32, hwnd, (HMENU)IDB_bezier, hInst, NULL); SendMessage(hBezier, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hImageBttn); hImageBttn = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_RECTANGLE)); hRectangle = CreateWindowEx( 0, "Button", NULL, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_BITMAP, 145, 15, 32, 32, hwnd, (HMENU)IDB_rectangle, hInst, NULL); SendMessage(hRectangle, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hImageBttn); hImageBttn = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_ELLIPSE)); hEllipse = CreateWindowEx( 0, "Button", NULL, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_BITMAP, 185, 15, 32, 32, hwnd, (HMENU)IDB_ellipse, hInst, NULL); SendMessage(hEllipse, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hImageBttn); hImageBttn = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_ERASER)); hEraser = CreateWindowEx( 0, "Button", NULL, WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_BITMAP, 225, 15, 32, 32, hwnd, (HMENU)IDB_eraser, hInst, NULL); SendMessage(hEraser, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hImageBttn); hFill = CreateWindowEx( 0, "Button", "Fill object", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, 10, 515, 100, 20, hwnd, (HMENU)IDB_fill, hInst, NULL); CreateWindowEx( 0, "Static", "Fill color", WS_VISIBLE | WS_CHILD | SS_LEFT, 120, 515, 75, 20, hwnd, (HMENU)0, hInst, NULL); CreateWindowEx( 0, "Static", "Line color", WS_VISIBLE | WS_CHILD | SS_LEFT, 230, 515, 70, 20, hwnd, (HMENU)0, hInst, NULL); CreateWindowEx( 0, "Static", "Border width", WS_VISIBLE | WS_CHILD | SS_LEFT, 350, 515, 100, 20, hwnd, (HMENU)0, hInst, NULL); hBorderW = CreateWindowEx( 0, "Edit", "1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 460, 515, 40, 20, hwnd, (HMENU)0, hInst, NULL); CreateWindowEx( 0, "Static", "Eraser width", WS_VISIBLE | WS_CHILD | SS_LEFT, 515, 515, 100, 20, hwnd, (HMENU)0, hInst, NULL); hEraserW = CreateWindowEx( 0, "Edit", "1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, 620, 515, 40, 20, hwnd, (HMENU)0, hInst, NULL); hClear = CreateWindowEx( NULL, "Button", "Clear", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 680, 515, 100, 20, hwnd, (HMENU)IDB_clear, GetModuleHandle(NULL), NULL); RegisterHotKey(hwnd, HK_dellipse, MOD_CONTROL, 0x45); RegisterHotKey(hwnd, HK_dblue, MOD_CONTROL, 0x43); break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); updateColorControls(hdc, fillColor, xFillPreview, yFillPreview); updateColorControls(hdc, borderColor, xStrokePreview, yStrokePreview); SelectObject(hdc, CreatePen(PS_SOLID, 1, RGB(0,0,0))); SelectObject(hdc, (HBRUSH)GetStockObject(WHITE_BRUSH)); Rectangle(hdc, drawingArea.left, drawingArea.top, drawingArea.right, drawingArea.bottom); EndPaint(hwnd, &ps); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDB_clear: Button_SetCheck(hPencil, BST_UNCHECKED); Button_SetCheck(hLine, BST_UNCHECKED); Button_SetCheck(hBezier, BST_UNCHECKED); Button_SetCheck(hRectangle, BST_UNCHECKED); Button_SetCheck(hEllipse, BST_UNCHECKED); Button_SetCheck(hEraser, BST_UNCHECKED); InvalidateRect(hwnd, &drawingArea, FALSE); InvalidateRect(hwnd, &drawingArea, TRUE); break; default: DefWindowProc(hwnd, WM_COMMAND, wParam, lParam); break; } break; case WM_GETMINMAXINFO: { LPMINMAXINFO mmi = (LPMINMAXINFO)lParam; mmi->ptMinTrackSize.x = 800; mmi->ptMinTrackSize.y = 550; mmi->ptMaxTrackSize.x = 850; mmi->ptMaxTrackSize.y = 600; break; } case WM_LBUTTONDOWN: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if(xMouse >= fillColorRect.left && xMouse <= fillColorRect.right) { if(yMouse >= fillColorRect.top && yMouse <= fillColorRect.bottom) { fillColor = colorSelect(hwnd, fillColor); updateColorControls(hdc, fillColor, xFillPreview, yFillPreview); } else if(yMouse >= borderColorRect.top && yMouse <= borderColorRect.bottom) { borderColor = colorSelect(hwnd, borderColor); updateColorControls(hdc, borderColor, xStrokePreview, yStrokePreview); } return 0; } if( (xMouse > drawingArea.left) && (xMouse < drawingArea.right) && (yMouse > drawingArea.top) && (yMouse < drawingArea.bottom) ) { width = getFromInput(hBorderW); point = getCurrentPointPosition(xMouse, yMouse, drawingArea, width); xMouse = point.x; yMouse = point.y; if((wParam == MK_LBUTTON) && (Button_GetCheck(hPencil) == BST_CHECKED)) { pointPen.x = xMouse; pointPen.y = yMouse; } if((wParam == MK_LBUTTON) && (Button_GetCheck(hLine) == BST_CHECKED)) { line.x = xMouse; line.y = yMouse; lineStarted = true; } if((wParam == MK_LBUTTON) && (Button_GetCheck(hRectangle) == BST_CHECKED)) { rectangle.left = xMouse; rectangle.top = yMouse; rectangleStarted = true; } if((wParam == MK_LBUTTON) && (Button_GetCheck(hEllipse) == BST_CHECKED)) { ellipse.left = xMouse; ellipse.top = yMouse; ellipseStarted = true; } if((wParam == MK_LBUTTON) && (Button_GetCheck(hBezier) == BST_CHECKED)) { if(bezierStage == 0) { bezierPoints[0] = point; bezierStage = 1; } else { bezierPoints[2] = point; bezierStage = 3; } } } break; case WM_LBUTTONUP: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); width = getFromInput(hBorderW); point = getCurrentPointPosition(xMouse, yMouse, drawingArea, width); xMouse = point.x; yMouse = point.y; borderPen = CreatePen(PS_SOLID, width, borderColor); if(Button_GetCheck(hFill) == BST_CHECKED) fillBrush = CreateSolidBrush(fillColor); else fillBrush = (HBRUSH)GetStockObject(NULL_BRUSH); if(lineStarted) { SelectObject(hdc, borderPen); MoveToEx(hdc, xMouse, yMouse, NULL); LineTo(hdc, line.x, line.y); DeleteObject(borderPen); lineStarted = false; } if(rectangleStarted) { SelectObject(hdc, borderPen); SelectObject(hdc, fillBrush); Rectangle(hdc, rectangle.left, rectangle.top, xMouse, yMouse); DeleteObject(borderPen); DeleteObject(fillBrush); rectangleStarted = false; } if(ellipseStarted) { SelectObject(hdc, borderPen); SelectObject(hdc, fillBrush); Ellipse(hdc, ellipse.left, ellipse.top, xMouse, yMouse); DeleteObject(borderPen); DeleteObject(fillBrush); ellipseStarted = false; } if(bezierStage == 1) { bezierPoints[1] = point; bezierStage = 2; } if(bezierStage == 3) { bezierPoints[3] = point; bezierStage = 0; SelectObject(hdc, borderPen); PolyBezier(hdc, bezierPoints, 4); DeleteObject(borderPen); } break; case WM_MOUSEMOVE: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if( (xMouse > drawingArea.left) && (xMouse < drawingArea.right) && (yMouse > drawingArea.top) && (yMouse < drawingArea.bottom) ) { if((wParam == MK_LBUTTON) && (Button_GetCheck(hPencil) == BST_CHECKED)) { width = getFromInput(hBorderW); point = getCurrentPointPosition(xMouse, yMouse, drawingArea, width); xMouse = point.x; yMouse = point.y; linePen = CreatePen(PS_SOLID, width, borderColor); SelectObject(hdc, linePen); MoveToEx(hdc, xMouse, yMouse, NULL); LineTo(hdc, pointPen.x, pointPen.y); DeleteObject(linePen); pointPen.x = xMouse; pointPen.y = yMouse; } if((wParam == MK_LBUTTON) && (Button_GetCheck(hEraser) == BST_CHECKED)) { width = getFromInput(hEraserW); point = getCurrentPointPosition(xMouse, yMouse, drawingArea, width); xMouse = point.x; yMouse = point.y; rect.left = point.x - (width / 2); rect.right = point.x + (width / 2); rect.top = point.y - (width / 2); rect.bottom = point.y + (width / 2); InvalidateRect(hwnd, &rect, FALSE); SendMessage(hwnd, WM_PAINT, 0, 0); } } break; case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); SetTextColor(hDC, RGB(255,69,0)); SetBkMode(hDC, TRANSPARENT); return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); } break; case WM_HOTKEY: { switch(wParam) { case HK_dellipse: Button_SetCheck(hPencil, BST_UNCHECKED); Button_SetCheck(hLine, BST_UNCHECKED); Button_SetCheck(hBezier, BST_UNCHECKED); Button_SetCheck(hRectangle, BST_UNCHECKED); Button_SetCheck(hEraser, BST_UNCHECKED); Button_SetCheck(hEllipse, BST_CHECKED); break; case HK_dblue: Button_SetCheck(hFill, BST_CHECKED); fillColor = RGB(0,0,255); updateColorControls(hdc, fillColor, xFillPreview, yFillPreview); break; default: break; } break; } case WM_CLOSE: if(MessageBox(hwnd, "Close application?", "Quit", MB_YESNO) == IDYES) DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
BOOL AngleArcToBezier(HDC hDC, int x0, int y0, int rx, int ry, double startangle, double sweepangle, double * err) { double XY[8]; POINT P[4]; // Compute bezier curve for arc centered along y axis // Anticlockwise: (0,-B), (x,-y), (x,y), (0,B) double B = ry * sin(sweepangle/2); double C = rx * cos(sweepangle/2); double A = rx - C; double X = A*4/3; double Y = B - X * (rx-A)/B; XY[0] = C; XY[1] = - B; XY[2] = C+X; XY[3] = - Y; XY[4] = C+X; XY[5] = Y; XY[6] = C; XY[7] = B; // rotate to the original angle double s = sin(startangle + sweepangle/2); double c = cos(startangle + sweepangle/2); double xy[8]; for (int i=0; i<4; i++) { if ( err ) { xy[i*2] = XY[i*2] * c - XY[i*2+1] * s; xy[i*2+1] = XY[i*2] * s + XY[i*2+1] * c; } P[i].x = x0 + (int) (XY[i*2] * c - XY[i*2+1] * s); P[i].y = y0 + (int) (XY[i*2] * s + XY[i*2+1] * c); } if ( err ) { double t = 0; * err = 0; while ( t<=1 ) { double x = ::P(t, xy[0], xy[2], xy[4], xy[6]) / rx; double y = ::P(t, xy[1], xy[3], xy[5], xy[7]) / ry; double r = sqrt(x*x + y*y); if ( fabs(r-1) > fabs(*err) ) *err = r-1; t += 0.01; } } return PolyBezier(hDC, P, 4); }
HRGN DrawChromeFrame(HDC hdc, RECT *pRect, COLORREF clrBorder, COLORREF clrBack) { HBRUSH hBackBrush = NULL; HBRUSH hBorderBrush; HRGN hRgn; hBorderBrush = CreateSolidBrush(clrBorder); hBackBrush = CreateSolidBrush (clrBack); POINT lpts[4], rpts[4]; int spread, eigth, sixth, quarter; int width = pRect->right - pRect->left; int height = pRect->bottom - pRect->top; if (1){//bottom spread = ((float)height) * 2/3; eigth = ((float)height) * 1/8; sixth = ((float)height) * 1/6; quarter = ((float)height) * 1/4; }else{ spread = ((float)width) * 2/3; eigth = ((float)width) * 1/8; sixth = ((float)width) * 1/6; quarter = ((float)width) * 1/4; } pRect->right += spread; lpts[3].x = pRect->left; lpts[3].y = pRect->bottom; lpts[2].x = pRect->left + sixth; lpts[2].y = pRect->bottom - eigth; lpts[1].x = pRect->left + spread - quarter; lpts[1].y = pRect->top + eigth; lpts[0].x = pRect->left + spread; lpts[0].y = pRect->top; rpts[3].x = pRect->right - spread; rpts[3].y = pRect->top; rpts[2].x = pRect->right - spread + quarter; rpts[2].y = pRect->top + eigth; rpts[1].x = pRect->right - sixth; rpts[1].y = pRect->bottom - eigth; rpts[0].x = pRect->right; rpts[0].y = pRect->bottom; MoveToEx(hdc, lpts[3].x, lpts[3].y, NULL); BeginPath(hdc); PolyBezier(hdc, lpts, sizeof(lpts)/sizeof(POINT)); //MoveToEx(hdc, lpts[0].x, lpts[0].y, NULL); LineTo(hdc, rpts[3].x, rpts[3].y); PolyBezier(hdc, rpts, sizeof(rpts)/sizeof(POINT)); //MoveToEx(hdc, rpts[0].x, rpts[0].y, NULL); LineTo(hdc, lpts[3].x, lpts[3].y); CloseFigure(hdc); EndPath(hdc); //StrokePath (hdc); FlattenPath(hdc); hRgn = PathToRegion(hdc); FillRgn(hdc, hRgn, hBackBrush); FrameRgn(hdc, hRgn, hBorderBrush, 1, 1); DeleteObject(hBorderBrush); DeleteObject(hBackBrush); HGDIOBJ hPen = NULL; HGDIOBJ hOldPen; hPen = CreatePen(PS_SOLID, 2, clrBack); hOldPen = SelectObject(hdc, hPen); DrawLine(hdc, rpts[0].x, rpts[0].y, lpts[3].x, lpts[3].y); SelectObject(hdc, hOldPen); DeleteObject(hPen); pRect->left += spread; pRect->right -= spread; return hRgn; }
void DrawPixels(HWND hwnd) { PAINTSTRUCT ps; RECT r; GetClientRect(hwnd, &r); if (r.bottom == 0) return; HDC hdc = BeginPaint(hwnd, &ps); // pixels for (int i = 0; i < 1000; i++) { int x = rand() % r.right; int y = rand() % r.bottom; SetPixel(hdc, x, y, RGB(rand() % 255, rand() % 255, rand() % 255)); } // rectangle Rectangle(hdc, 30, 30, 240, 140); // pens and lines (stroke) HPEN hPen1 = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); HPEN hPen2 = CreatePen(PS_DASH, 1, RGB(0, 0, 0)); HPEN hPen3 = CreatePen(PS_DOT, 1, RGB(0, 0, 0)); HPEN hPen4 = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0)); HPEN hPen5 = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 0)); HPEN holdPen = SelectObject(hdc, hPen1); MoveToEx(hdc, 50, 30, NULL); LineTo(hdc, 200, 30); SelectObject(hdc, hPen2); MoveToEx(hdc, 50, 50, NULL); LineTo(hdc, 200, 50); SelectObject(hdc, hPen2); MoveToEx(hdc, 50, 70, NULL); LineTo(hdc, 200, 70); SelectObject(hdc, hPen3); MoveToEx(hdc, 50, 90, NULL); LineTo(hdc, 200, 90); SelectObject(hdc, hPen4); MoveToEx(hdc, 50, 110, NULL); LineTo(hdc, 200, 110); SelectObject(hdc, holdPen); DeleteObject(hPen1); DeleteObject(hPen2); DeleteObject(hPen3); DeleteObject(hPen4); DeleteObject(hPen5); // brushes and fill HPEN hPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0)); holdPen = SelectObject(hdc, hPen); HBRUSH hBrush1 = CreateSolidBrush(RGB(121, 90, 0)); HBRUSH hBrush2 = CreateSolidBrush(RGB(240, 63, 19)); HBRUSH hBrush3 = CreateSolidBrush(RGB(240, 210, 18)); HBRUSH hBrush4 = CreateSolidBrush(RGB(9, 189, 21)); HBRUSH holdBrush = SelectObject(hdc, hBrush1); int top = 200; int size = 70; Rectangle(hdc, 30, top, 100, top+size); SelectObject(hdc, hBrush2); Rectangle(hdc, 110, top, 180, top+size); SelectObject(hdc, hBrush3); Rectangle(hdc, 30, top+70, 100, top+size+70); SelectObject(hdc, hBrush4); Rectangle(hdc, 110, top+70, 180, top+size+70); SelectObject(hdc, holdPen); SelectObject(hdc, holdBrush); DeleteObject(hPen); DeleteObject(hBrush1); DeleteObject(hBrush2); DeleteObject(hBrush3); DeleteObject(hBrush4); // draw shapes int left = 370; Ellipse(hdc, left, 30, left + 60, 90); RoundRect(hdc, left+80, 30, left+160, 90, 15, 20); Chord(hdc, 270, 30, 360, 90, 270, 45, 360, 45); const POINT polygon[10] = { left+30, 145, left+85, 165, left+105, 110, left+65, 125, left+30, 105 }; const POINT bezier[4] = {280, 160, 320, 160, 325, 110, 350, 110}; Polygon(hdc, polygon, 5); PolyBezier(hdc, bezier, 4); // draw text DWORD color; HFONT hFont, holdFont; static wchar_t *ver1 = L"Not marble, nor the gilded monuments"; static wchar_t *ver2 = L"Of princes, shall outlive this powerful rhyme;"; static wchar_t *ver3 = L"But you shall shine more bright in these contents"; static wchar_t *ver4 = L"Than unswept stone, besmear'd with sluttish time."; static wchar_t *ver5 = L"When wasteful war shall statues overturn,"; static wchar_t *ver6 = L"And broils root out the work of masonry,"; static wchar_t *ver7 = L"Nor Mars his sword, nor war's quick fire shall burn"; static wchar_t *ver8 = L"The living record of your memory."; static wchar_t *ver9 = L"'Gainst death, and all oblivious enmity"; static wchar_t *ver10 = L"Shall you pace forth; your praise shall still find room"; static wchar_t *ver11 = L"Even in the eyes of all posterity"; static wchar_t *ver12 = L"That wear this world out to the ending doom."; static wchar_t *ver13 = L"So, till the judgment that yourself arise,"; static wchar_t *ver14 = L"You live in this, and dwell in lovers' eyes."; color = GetSysColor(COLOR_BTNFACE); SetBkColor(hdc, color); hFont = CreateFontW(15, 0, 0, 0, FW_MEDIUM, 0, 0, 0, 0, 0, 0, 0, 0, L"Georgia"); holdFont = SelectObject(hdc, hFont); left = 270; top = 160; TextOutW(hdc, left, top + 20, ver1, lstrlenW(ver1)); TextOutW(hdc, left, top + 40, ver2, lstrlenW(ver2)); TextOutW(hdc, left, top + 60, ver3, lstrlenW(ver3)); TextOutW(hdc, left, top + 80, ver4, lstrlenW(ver4)); TextOutW(hdc, left, top + 100, ver5, lstrlenW(ver5)); TextOutW(hdc, left, top + 120, ver6, lstrlenW(ver6)); TextOutW(hdc, left, top + 140, ver7, lstrlenW(ver7)); TextOutW(hdc, left, top + 160, ver8, lstrlenW(ver8)); TextOutW(hdc, left, top + 180, ver9, lstrlenW(ver9)); TextOutW(hdc, left, top + 200, ver10, lstrlenW(ver10)); TextOutW(hdc, left, top + 220, ver11, lstrlenW(ver11)); TextOutW(hdc, left, top + 240, ver12, lstrlenW(ver12)); TextOutW(hdc, left, top + 260, ver13, lstrlenW(ver13)); TextOutW(hdc, left, top + 280, ver14, lstrlenW(ver14)); SelectObject(hdc, holdFont); DeleteObject(hFont); // draw bitmap BITMAP bitmap; HDC hdcMem; HGDIOBJ oldBitmap; hdcMem = CreateCompatibleDC(hdc); oldBitmap = SelectObject(hdcMem, hBitmap); GetObject(hBitmap, sizeof(bitmap), &bitmap); BitBlt(hdc, 550, 5, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, oldBitmap); DeleteDC(hdcMem); EndPaint(hwnd, &ps); }
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND button, BezierTool, LineTool,Pen,EllipseTool,RectangleTool,EraserTool; int width; int xMouse, yMouse; HDC hdc = GetDC(hwnd); static POINT line, lineStart; static BOOL lineStarted; static BOOL ellipseStarted; static RECT ellipse; static BOOL rectangleStarted; static RECT rectangle; static int bezierStage = 0; static POINT bezierPoints[4]; static POINT bezierPoint; HDC hdcMem; BITMAP bitmap; HGDIOBJ oldBitmap; HBITMAP hbmplogo = NULL; hbmplogo = (HBITMAP)LoadImage(hInstance, "paint.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); GetObject(hbmplogo, sizeof(bitmap), &bitmap); HDC hDC; PAINTSTRUCT Ps; HBRUSH NewBrush; HPEN linePen; HPEN linePen2; HPEN linePen3; linePen= CreatePen(PS_SOLID,2,RGB(255,255,0)); linePen2=CreatePen(PS_DASHDOTDOT,4,RGB(255,0,255)); linePen3=CreatePen(PS_STYLE_MASK,6,RGB(0,128,255)); SelectObject(hdc,linePen); POINT Pt[4] = { { 20, 12 }, { 88, 246 }, { 364, 192 }, { 250, 48 } }; PolyBezierTo(hdc,Pt,4); switch (message) /* handle the messages */ { case WM_CREATE: BezierTool = CreateWindowEx( 0, "Button", "Bezier", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 30, 250, 180, 20, hwnd, (HMENU)IDB_BEZIER, hInstance, NULL); LineTool = CreateWindowEx( 0, "Button", "Line", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 30, 280, 180, 20, hwnd, (HMENU)IDB_LINE, hInstance, NULL); Pen = CreateWindowEx( 0, "Button", "Pen", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 30, 310, 180, 20, hwnd, (HMENU)IDB_PEN, hInstance, NULL); EllipseTool = CreateWindowEx( 0, "Button", "Ellipse", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 30, 340, 180, 20, hwnd, (HMENU)IDB_ELLIPSE, hInstance, NULL); RectangleTool = CreateWindowEx( 0, "Button", "Rectangle", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 30, 370, 180, 20, hwnd, (HMENU)IDB_RECTANGLE, hInstance, NULL); EraserTool = CreateWindowEx( 0, "Button", "Eraser", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 30, 415, 180, 20, hwnd, (HMENU)IDB_ERASER, hInstance, NULL); hbmplogo = (HBITMAP)LoadImage(hInstance, "paint.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); return 0; case WM_MOUSEMOVE: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if (xMouse > 250 && xMouse < 880 && yMouse > 20 && yMouse < 550 ) { if(wParam & MK_LBUTTON) { if (Button_GetCheck(Pen) == BST_CHECKED) { width = 2; linePen = CreatePen(PS_SOLID, width, RGB(0, 0, 0)); SelectObject(hdc, linePen); MoveToEx(hdc, xMouse, yMouse, NULL); LineTo(hdc, pointPen.x, pointPen.y); DeleteObject(linePen); pointPen.x = xMouse; pointPen.y = yMouse; } if (Button_GetCheck(LineTool) == BST_CHECKED) { width = 2; // draw previous line with white linePen = CreatePen(PS_SOLID, width, RGB(255, 255, 255)); SelectObject(hdc, linePen); MoveToEx(hdc, lineStart.x, lineStart.y, NULL); LineTo(hdc, line.x, line.y); DeleteObject(linePen); // draw the line linePen = CreatePen(PS_SOLID, width, RGB(0, 0, 0)); SelectObject(hdc, linePen); MoveToEx(hdc, lineStart.x, lineStart.y, NULL); LineTo(hdc, xMouse, yMouse); DeleteObject(linePen); line.x = xMouse; line.y = yMouse; } // Eraser if((wParam == MK_LBUTTON) && (Button_GetCheck(EraserTool) == BST_CHECKED)) { width = 6; rectangle.left = xMouse - (width / 2); rectangle.right = xMouse + (width / 2); rectangle.top = yMouse - (width / 2); rectangle.bottom = yMouse + (width / 2); InvalidateRect(hwnd, &rectangle, FALSE); SendMessage(hwnd, WM_PAINT, 0, 0); //ValidateRect(hwnd, &rect); } } } break; case WM_LBUTTONUP : xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); if (xMouse > 250 && xMouse < 880 && yMouse > 20 && yMouse < 550 ) { if (Button_GetCheck(LineTool) == BST_CHECKED) { width = 2; // draw previous line with white SelectObject(hdc, CreatePen(PS_SOLID, width, RGB(0, 0, 0))); MoveToEx(hdc, lineStart.x, lineStart.y, NULL); LineTo(hdc, line.x, line.y); // draw the line linePen = CreatePen(PS_SOLID, width, RGB(0, 0, 0)); SelectObject(hdc, linePen); MoveToEx(hdc, lineStart.x, lineStart.y, NULL); LineTo(hdc, xMouse, yMouse); DeleteObject(linePen); line.x = xMouse; line.y = yMouse; } if(ellipseStarted) { SelectObject(hdc, linePen2); SelectObject(hdc, NewBrush); Ellipse(hdc, ellipse.left, ellipse.top, xMouse, yMouse); DeleteObject(linePen2); DeleteObject(NewBrush); ellipseStarted = false; } if(rectangleStarted) { SelectObject(hdc, linePen); SelectObject(hdc, NewBrush); Rectangle(hdc, rectangle.left, rectangle.top, xMouse, yMouse); DeleteObject(linePen); DeleteObject(NewBrush); rectangleStarted = false; } if(bezierStage == 1) { bezierPoint.x = xMouse; bezierPoint.y = yMouse; bezierPoints[1] = bezierPoint; bezierStage = 2; } if(bezierStage == 3) { bezierPoint.x = xMouse; bezierPoint.y = yMouse; bezierPoints[3] = bezierPoint; bezierStage = 0; SelectObject(hdc, linePen3); PolyBezier(hdc, bezierPoints, 4); DeleteObject(linePen3); } } break; case WM_LBUTTONDOWN: xMouse = GET_X_LPARAM(lParam); yMouse = GET_Y_LPARAM(lParam); //250, 20, 880, 550 if (xMouse > 250 && xMouse < 880 && yMouse > 20 && yMouse < 550 ) { if(wParam == MK_LBUTTON) { if (Button_GetCheck(Pen) == BST_CHECKED) { pointPen.x = xMouse; pointPen.y = yMouse; } if (Button_GetCheck(LineTool) == BST_CHECKED) { lineStart.x = xMouse; lineStart.y = yMouse; line.x = xMouse; line.y = yMouse; } if((wParam == MK_LBUTTON) && (Button_GetCheck(EllipseTool) == BST_CHECKED)) { ellipse.left = xMouse; ellipse.top = yMouse; ellipseStarted = true; } if((wParam == MK_LBUTTON) && (Button_GetCheck(RectangleTool) == BST_CHECKED)) { rectangle.left = xMouse; rectangle.top = yMouse; rectangleStarted = true; } if((wParam == MK_LBUTTON) && (Button_GetCheck(BezierTool) == BST_CHECKED)) { if(bezierStage == 0) { bezierPoint.x = xMouse; bezierPoint.y = yMouse; bezierPoints[0] = bezierPoint; bezierStage = 1; } else { bezierPoint.x = xMouse; bezierPoint.y = yMouse; bezierPoints[2] = bezierPoint; bezierStage = 3; } } } } break; case WM_PAINT: hDC = BeginPaint(hwnd, &Ps); NewBrush = CreateSolidBrush(RGB(255, 255, 255)); SelectObject(hDC, NewBrush); Rectangle(hDC, 250, 20, 880, 550); DeleteObject(NewBrush); //PolyBezier(hDC, Pt, 4); //EndPaint(hWnd, &Ps); // Draw logo hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hbmplogo); // Copy the bits from the memory DC into the current dc BitBlt(hdc, 10, 10, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY); // Restore the old bitmap DeleteDC(hdcMem); EndPaint(hwnd, &Ps); break; case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; static RECT rect,oldRect,invalidationRect; //The oldRect is used for window resizing handling , the invalidationRect for invalidating only the drawing area static BOOL drawing_circle=FALSE,drawing_square=TRUE,drawing_bezier=FALSE,//Checks what is being drawn at the moment first_point=TRUE, //Checks if the first point of the bezier is being drawn button_pressed_in_area=FALSE, //Checks if the button was pressed and if it happened inside the drawing area mouse_moving=FALSE; //Checks if the mouse is moving in order to paint the tracing of the object static HDC hdc, hdcMem; static HBITMAP hBitmap; BITMAP bitmap; static int figureCount=0; //Counts the number of figures in the drawing area static POINT arrayPoints[100][5]; //The array that holds the data of the figures static float xDisp,yDisp,slope,displacement; //Used to move and resize the pictures drawn . The last two variables are used to calculate the function //that the points will move on when resizing (the resize is a convergence towards the center) static int xFin=0,yFin=0,xFinSecond=0,yFinSecond=0; //Used to draw the tracing of elemens with the last two needed for Bezier only static int resizeCount; //Used to limit the resize to a certain number of times switch (message) /* handle the messages */ { case WM_CREATE: GetClientRect(hwnd,&rect); //oldRect gets the same value as current rect as to avoid division by 0 and unintended resizing at the beginning oldRect=rect; //Creates the needed switches CreateButtons(hwnd,rect); // Loads the bitmap from resources hBitmap = LoadBitmap(hInst,MAKEINTRESOURCE(LOGO)); GetObject(hBitmap,sizeof(BITMAP),&bitmap); break; case WM_SIZE: GetClientRect(hwnd,&rect); //Resizes all buttons based on the window size MoveWindow(hwndSquareButton,rect.right*3/4,rect.bottom/32,rect.right/8,30,TRUE); MoveWindow(hwndCircleButton,rect.right*7/8,rect.bottom/32,rect.right/8,30,TRUE); MoveWindow(hwndBezierButton,rect.right*3/4,rect.bottom/8,rect.right/8,30,TRUE); //Set the displacement of the drawings inside the window to new , moved coordinates xDisp=(float)rect.right/oldRect.right; yDisp=(float)rect.bottom/oldRect.bottom; oldRect.bottom=rect.bottom; oldRect.right=rect.right; for(int i=0; i<figureCount; i++) { for(int j=0; j<4; j++) { arrayPoints[i][j].x*=xDisp; arrayPoints[i][j].y*=yDisp; } } InvalidateRect(hwnd,NULL,TRUE); break; case WM_COMMAND: //Sets the buttons to active and puts the flags in the needed positions switch(wParam) { case ID_SWITCH_CIRCLE: SendMessage(hwndCircleButton,BM_SETCHECK,1,0); SendMessage(hwndBezierButton,BM_SETCHECK,0,0); SendMessage(hwndSquareButton,BM_SETCHECK,0,0); drawing_bezier=drawing_square=FALSE; drawing_circle=TRUE; break; case ID_SWITCH_SQUARE: SendMessage(hwndCircleButton,BM_SETCHECK,0,0); SendMessage(hwndBezierButton,BM_SETCHECK,0,0); SendMessage(hwndSquareButton,BM_SETCHECK,1,0); drawing_bezier=drawing_circle=FALSE; drawing_square=TRUE; break; case ID_SWITCH_BEZIER: SendMessage(hwndCircleButton,BM_SETCHECK,0,0); SendMessage(hwndBezierButton,BM_SETCHECK,1,0); SendMessage(hwndSquareButton,BM_SETCHECK,0,0); drawing_square=drawing_circle=FALSE; drawing_bezier=TRUE; break; } break; case WM_RBUTTONDOWN: //The setting up of invalidation region GetClientRect(hwnd,&rect); invalidationRect.right=rect.right*3/4-16; invalidationRect.top=rect.top+130; invalidationRect.bottom=rect.bottom-5; invalidationRect.left=rect.right*1/4+16; //The deletion a figure and refreshing the picture figureCount--; if(figureCount<0) figureCount=0; InvalidateRect(hwnd,&invalidationRect,TRUE); break; case WM_MOUSEMOVE: //Exits case in case the mouse is out of the needed area if(!button_pressed_in_area) break; mouse_moving=TRUE; //invalidation GetClientRect(hwnd,&rect); invalidationRect.right=rect.right*3/4-16; invalidationRect.top=rect.top+130; invalidationRect.bottom=rect.bottom-5; invalidationRect.left=rect.right*1/4+16; //Checks if the moving is being done in the drawing area and ends drawing in case it isn't if ((LOWORD(lParam)<rect.right/4+20) || (LOWORD(lParam)>rect.right*3/4-20) || (HIWORD(lParam)<135) || (HIWORD(lParam)>rect.bottom-6)) { SendMessage(hwnd,WM_LBUTTONUP,NULL,lParam) ; break; } hdc=GetDC(hwnd); //Depending on the selected drawing sets the points for the tracing of figures if (drawing_circle) { xFin=LOWORD(lParam); yFin=HIWORD(lParam); } if (drawing_square) { xFin=LOWORD(lParam); yFin=HIWORD(lParam); } if (drawing_bezier && !first_point) { xFin=LOWORD(lParam); yFin=HIWORD(lParam); } else if (drawing_bezier) { xFinSecond=LOWORD(lParam); yFinSecond=HIWORD(lParam); } //Send message to repaint drawing area InvalidateRect(hwnd,&invalidationRect,TRUE); ReleaseDC(hwnd,hdc); break; case WM_LBUTTONDOWN: //Checks if the button clicking is being done in the drawing area and sets focus to main window SetFocus(hwnd); GetClientRect(hwnd,&rect); if ((LOWORD(lParam)<rect.right/4+14) || (LOWORD(lParam)>rect.right*3/4-14) || (HIWORD(lParam)<125) || (HIWORD(lParam)>rect.bottom-6)) break; button_pressed_in_area=TRUE; hdc=GetDC(hwnd); //Gets initial points for the figure being drawn and sets a information value in order to read the right thing from the array afterwards if (drawing_square) { arrayPoints[figureCount][4].x=ID_SWITCH_SQUARE; arrayPoints[figureCount][0].x=LOWORD(lParam); arrayPoints[figureCount][0].y=HIWORD(lParam); } if (drawing_bezier && first_point) { arrayPoints[figureCount][4].x=ID_SWITCH_BEZIER; arrayPoints[figureCount][0].x=LOWORD(lParam); arrayPoints[figureCount][0].y=HIWORD(lParam); first_point=FALSE; } else if (drawing_bezier) { first_point=TRUE; figureCount--; arrayPoints[figureCount][2].x=LOWORD(lParam); arrayPoints[figureCount][2].y=HIWORD(lParam); } if (drawing_circle) { arrayPoints[figureCount][4].x=ID_SWITCH_CIRCLE; arrayPoints[figureCount][0].x=LOWORD(lParam); arrayPoints[figureCount][0].y=HIWORD(lParam); } ReleaseDC(hwnd,hdc); break; case WM_LBUTTONUP: //Makes sure the drawing started inside the canvas if(!button_pressed_in_area) break; mouse_moving=FALSE; //invalidation GetClientRect(hwnd,&rect); invalidationRect.right=rect.right*3/4-16; invalidationRect.top=rect.top+130; invalidationRect.bottom=rect.bottom-5; invalidationRect.left=rect.right*1/4+16; hdc=GetDC(hwnd); //Gets the end points of the figures if (drawing_square) { arrayPoints[figureCount][1].x=LOWORD(lParam); arrayPoints[figureCount][1].y=HIWORD(lParam); } if (drawing_bezier && !first_point) { arrayPoints[figureCount][1].x=LOWORD(lParam); arrayPoints[figureCount][1].y=HIWORD(lParam); } else if (drawing_bezier) { arrayPoints[figureCount][3].x=LOWORD(lParam); arrayPoints[figureCount][3].y=HIWORD(lParam); InvalidateRect(hwnd,&invalidationRect,TRUE); } if (drawing_circle) { arrayPoints[figureCount][1].x=LOWORD(lParam); arrayPoints[figureCount][1].y=HIWORD(lParam); } //Increments nr of figures figureCount++; button_pressed_in_area=FALSE; //The bezier uses 4 points instead of 2 like the others so different actions when invalidating if (!drawing_bezier) { InvalidateRect(hwnd,&invalidationRect,TRUE); } ReleaseDC(hwnd,hdc); break; case WM_KEYDOWN: //invalidation GetClientRect(hwnd,&rect); invalidationRect.right=rect.right*3/4-16; invalidationRect.top=rect.top+130; invalidationRect.bottom=rect.bottom-5; invalidationRect.left=rect.right*1/4+16; //Resizes canvas based on convergence on the line formed by the center point of the canvas and a point of the figure switch(wParam) { case VK_UP: if (resizeCount<0) break; for(int i=0; i<figureCount; i++) { for(int j=0; j<4; j++) { slope=(arrayPoints[i][j].y-(rect.bottom-126)/2)/(float)(arrayPoints[i][j].x-rect.right/2); displacement=arrayPoints[i][j].y-slope*arrayPoints[i][j].x; arrayPoints[i][j].x=(rect.right/2)-(rect.right/2-arrayPoints[i][j].x)*1.1; arrayPoints[i][j].y=roundf(arrayPoints[i][j].x*slope+displacement); } } resizeCount--; break; case VK_DOWN: if(resizeCount>10) break; for(int i=0; i<figureCount; i++) { for(int j=0; j<4; j++) { slope=(arrayPoints[i][j].y-(rect.bottom-126)/2)/(float)(arrayPoints[i][j].x-rect.right/2); displacement=arrayPoints[i][j].y-slope*arrayPoints[i][j].x; arrayPoints[i][j].x=(rect.right/2)-(rect.right/2-arrayPoints[i][j].x)*0.9; arrayPoints[i][j].y=roundf(arrayPoints[i][j].x*slope+displacement); } } resizeCount++; break; } InvalidateRect(hwnd,&invalidationRect,TRUE); break; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); GetClientRect(hwnd,&rect); //Create figures SelectObject(hdc,GetStockObject(NULL_BRUSH)); for (int i=0; i<figureCount; i++) { switch(arrayPoints[i][4].x) { case ID_SWITCH_SQUARE: Rectangle(hdc,arrayPoints[i][0].x,arrayPoints[i][0].y,arrayPoints[i][1].x,arrayPoints[i][1].y); break; case ID_SWITCH_CIRCLE: Ellipse(hdc,arrayPoints[i][0].x,arrayPoints[i][0].y,arrayPoints[i][1].x,arrayPoints[i][1].y); break; case ID_SWITCH_BEZIER: PolyBezier(hdc,arrayPoints[i],4); break; } } //Create traces if (mouse_moving) { if (drawing_circle) { Ellipse(hdc,arrayPoints[figureCount][0].x,arrayPoints[figureCount][0].y,xFin,yFin); } if (drawing_bezier && !first_point) { MoveToEx(hdc,arrayPoints[figureCount][0].x,arrayPoints[figureCount][0].y,NULL); LineTo(hdc,xFin,yFin); } else if (drawing_bezier) { MoveToEx(hdc,arrayPoints[figureCount][0].x,arrayPoints[figureCount][0].y,NULL); LineTo(hdc,xFin,yFin); MoveToEx(hdc,arrayPoints[figureCount][2].x,arrayPoints[figureCount][2].y,NULL); LineTo(hdc,xFinSecond,yFinSecond); } if (drawing_square) { Rectangle(hdc,arrayPoints[figureCount][0].x,arrayPoints[figureCount][0].y,xFin,yFin); } } SelectObject(hdc,GetStockObject(WHITE_BRUSH)); //Create the gradients CreateGradient(hdc,0,0,rect.right/4+10,rect.bottom+1); CreateGradient(hdc,rect.right*3/4-10,0,rect.right+1,rect.bottom+1); //Creates the background for drawing DrawTheWorkingArea(hdc,rect); //Adds the lines to the drawing DrawTheLines(hdc,rect); //Adds figures to the mix DrawGeometry(hdc,rect); //Make bmp hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem,hBitmap); BitBlt(hdc,rect.right/4+16,6,185,120,hdcMem,0,0,SRCCOPY); DeleteDC(hdcMem); EndPaint(hwnd,&ps); break; case WM_CTLCOLORSTATIC: SetBkMode((HDC)wParam,TRANSPARENT); return (LRESULT)GetStockObject(NULL_BRUSH); case WM_GETMINMAXINFO: //Setting the minimal size for the window MINMAXINFO *ptMinMax; ptMinMax=(MINMAXINFO*)lParam; ptMinMax->ptMinTrackSize.x=450; ptMinMax->ptMinTrackSize.y=300; break; case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; }
// // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; static POINT apt[4]; static int cxClient, cyClient; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); apt[0].x = cxClient/4; apt[0].y = cyClient/2; apt[1].x = cxClient/2; apt[1].y = cyClient/4; apt[2].x = cxClient/2; apt[2].y = cyClient/4*3; apt[3].x = cxClient/4*3; apt[3].y = cyClient/2; break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... PolyBezier(hdc, apt, 4); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN: hdc = GetDC(hWnd); SelectObject(hdc, GetStockObject(WHITE_PEN)); PolyBezier(hdc, apt, 4); apt[1].x = LOWORD(lParam); apt[1].y = HIWORD(lParam); SelectObject(hdc, GetStockObject(BLACK_PEN)); PolyBezier(hdc, apt, 4); ReleaseDC(hWnd, hdc); break; case WM_RBUTTONDOWN: hdc = GetDC(hWnd); SelectObject(hdc, GetStockObject(WHITE_PEN)); PolyBezier(hdc, apt, 4); apt[2].x = LOWORD(lParam); apt[2].y = HIWORD(lParam); SelectObject(hdc, GetStockObject(BLACK_PEN)); PolyBezier(hdc, apt, 4); ReleaseDC(hWnd, hdc); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }