#include "ImgPF.h" static L_VOID Angle_OnPaint (HWND hWnd); static L_VOID Angle_OnDestroy (HWND hWnd); static L_VOID Angle_OnLButtonDown (HWND hWnd, L_BOOL bDoubleClick, L_INT nX, L_INT nY, L_UINT uKeyFlags); static L_VOID Angle_OnMouseMove (HWND hWnd, L_INT nX, L_INT nY, L_UINT uKeyFlags); static L_VOID Angle_OnLButtonUp (HWND hWnd, L_INT nX, L_INT nY, L_UINT uKeyFlags); typedef struct tagANGLCTRL { WNDPROC wndProcOld; L_INT nRange; L_INT nPrec; L_INT nApplyFilter; POINT ptDir; POINT ptLArrow; POINT ptRArrow; L_INT nAngle; L_BOOL bMove; L_INT nAttachedText; } ANGLCTRL, L_FAR * LPANGLCTRL; LRESULT CALLBACK AngleWP (HWND hAngleWnd, L_UINT uMessage, WPARAM wParam, LPARAM lParam) { LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hAngleWnd, GWL_USERDATA); switch(uMessage) { HANDLE_MSG(hAngleWnd, WM_LBUTTONUP, Angle_OnLButtonUp); HANDLE_MSG(hAngleWnd, WM_LBUTTONDOWN, Angle_OnLButtonDown); HANDLE_MSG(hAngleWnd, WM_PAINT, Angle_OnPaint); HANDLE_MSG(hAngleWnd, WM_DESTROY, Angle_OnDestroy); HANDLE_MSG(hAngleWnd, WM_MOUSEMOVE, Angle_OnMouseMove); } return DefWindowProc(hAngleWnd, uMessage, wParam, lParam); } static L_VOID Angle_OnPaint(HWND hWnd) { HBITMAP hBitmap; HDC hDCMem, hDC; PAINTSTRUCT ps; RECT rcRect, rcSmallRect; HPEN hPen, hPen1, hPen2, hPen3, hPen4, hPen5; HBRUSH hBrush; L_INT nX, nY; LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hWnd, GWL_USERDATA); L_INT nRectWidth; L_INT nRectHeight; L_DOUBLE Deg45; GetClientRect(hWnd, &rcRect); hDC = BeginPaint(hWnd, &ps); hBitmap = CreateCompatibleBitmap(hDC, rcRect.right - rcRect.left , rcRect.bottom - rcRect.top); hPen = CreatePen(PS_SOLID, 1, RGB(240, 240, 240)); hPen1 = CreatePen(PS_SOLID, 1, RGB(210 ,210, 210)); hPen2 = CreatePen(PS_SOLID, 1, RGB(144, 144, 144)); hPen3 = CreatePen(PS_SOLID, 1, RGB(164, 164, 164)); hPen4 = CreatePen(PS_SOLID, 3, RGB( 0, 0, 0)); hPen5 = GetStockObject(NULL_PEN); hBrush = GetSysColorBrush(COLOR_BTNFACE); hDCMem = CreateCompatibleDC(hDC); Deg45 = sin(45 * 3.14159 / 180); nRectWidth = RECTWIDTH(&rcRect); nRectHeight = RECTHEIGHT(&rcRect); SelectBitmap(hDCMem, hBitmap); SelectPen(hDCMem, hPen); SelectBrush(hDCMem, hBrush); FillRect(hDCMem, &rcRect, hBrush); Arc(hDCMem, rcRect.left, rcRect.top, rcRect.right, rcRect.bottom, nRectWidth - (nRectWidth >> 2), nRectHeight >> 2, (nRectWidth >> 2), nRectHeight - (nRectHeight >> 2)); SelectPen(hDCMem, hPen1); Arc(hDCMem, rcRect.left + 1, rcRect.top + 1, rcRect.right, rcRect.bottom, nRectWidth - (nRectWidth >> 2), nRectHeight >> 2, (nRectWidth >> 2), nRectHeight - (nRectHeight >> 2)); SelectPen(hDCMem, hPen2); Arc(hDCMem, rcRect.left, rcRect.top, rcRect.right, rcRect.bottom, (nRectWidth >> 2), nRectHeight - (nRectHeight >> 2), nRectWidth - (nRectWidth >> 2), nRectHeight >> 2); SelectPen(hDCMem, hPen3); nX = (nRectWidth >> 1) + (L_INT)((nRectWidth >> 1) * Deg45); nY = (nRectHeight >> 1) - (L_INT)((nRectHeight >> 1) * Deg45); MoveToEx(hDCMem, nX, nY, NULL); LineTo(hDCMem, nX - 4, nY + 4); nX = (nRectWidth >> 1) - (L_INT)((nRectWidth >> 1) * Deg45); MoveToEx(hDCMem, nX + 1, nY + 1, NULL); LineTo(hDCMem, nX + 4, nY + 4); nY = (nRectHeight >> 1) + (L_INT)((nRectHeight >> 1) * Deg45); MoveToEx(hDCMem, nX + 1, nY - 1, NULL); LineTo(hDCMem, nX + 4, nY - 4); nX = (nRectWidth >> 1) + (L_INT)((nRectWidth >> 1) * Deg45); MoveToEx(hDCMem, nX - 1, nY - 1, NULL); LineTo(hDCMem, nX - 4, nY - 4); nX = (nRectWidth >> 1); nY = rcRect.top; MoveToEx(hDCMem, nX, nY + 1, NULL); LineTo(hDCMem, nX, nY + 5); nX = (nRectWidth >> 1); nY = rcRect.bottom; MoveToEx(hDCMem, nX, nY - 2, NULL); LineTo(hDCMem, nX, nY - 5); nX = rcRect.left; nY = nRectHeight >> 1; MoveToEx(hDCMem, nX + 1, nY, NULL); LineTo(hDCMem, nX + 5, nY); nX = rcRect.right; nY = nRectHeight >> 1; MoveToEx(hDCMem, nX - 2, nY, NULL); LineTo(hDCMem, nX - 5, nY); SelectPen(hDCMem, hPen4); MoveToEx(hDCMem, ((nRectWidth) >> 1) , (nRectHeight >> 1), NULL); LineTo(hDCMem, pAngleCtrl->ptDir.x, pAngleCtrl->ptDir.y); LineTo(hDCMem, (nRectWidth >> 1) + (L_INT)(((nRectWidth >> 1) - 8) * cos(((360 * pAngleCtrl->nPrec - pAngleCtrl->nAngle) / pAngleCtrl->nPrec + 8) * 3.14159 / 180)), (nRectHeight >> 1) + (L_INT)(((nRectHeight >> 1) - 8) * sin(((360 * pAngleCtrl->nPrec - pAngleCtrl->nAngle) / pAngleCtrl->nPrec + 8) * 3.14159 / 180))); MoveToEx(hDCMem, pAngleCtrl->ptDir.x, pAngleCtrl->ptDir.y, NULL); LineTo(hDCMem, (nRectWidth >> 1) + (L_INT)(((nRectWidth >> 1) - 8) * cos(((360 * pAngleCtrl->nPrec - pAngleCtrl->nAngle) / pAngleCtrl->nPrec - 8) * 3.14159 / 180)), (nRectHeight >> 1) + (L_INT)(((nRectHeight >> 1) - 8) * sin(((360 * pAngleCtrl->nPrec - pAngleCtrl->nAngle) / pAngleCtrl->nPrec - 8) * 3.14159 / 180))); rcSmallRect.left = (nRectWidth >> 1) - (nRectWidth / 10); rcSmallRect.top = (nRectHeight >> 1) - (nRectHeight / 10); rcSmallRect.right = (nRectWidth >> 1) + (nRectWidth / 10); rcSmallRect.bottom = (nRectHeight >> 1) + (nRectHeight / 10); SelectPen(hDCMem, hPen5); //SelectBrush(hDCMem, GetStockBrush(WHITE_BRUSH)); Ellipse(hDCMem, rcSmallRect.left, rcSmallRect.top, rcSmallRect.right + 1, rcSmallRect.bottom + 1); SelectPen(hDCMem, hPen1); Arc(hDCMem, rcSmallRect.left, rcSmallRect.top, rcSmallRect.right, rcSmallRect.bottom, rcSmallRect.right - (RECTWIDTH(&rcSmallRect) / 20), rcSmallRect.top + (RECTHEIGHT(&rcSmallRect) / 20), rcSmallRect.left + (RECTWIDTH(&rcSmallRect) / 20), rcSmallRect.bottom - (RECTHEIGHT(&rcSmallRect) / 20)); SelectPen(hDCMem, hPen2); Arc(hDCMem, rcSmallRect.left, rcSmallRect.top, rcSmallRect.right, rcSmallRect.bottom, rcSmallRect.left + (RECTWIDTH(&rcSmallRect) / 20), rcSmallRect.bottom - (RECTHEIGHT(&rcSmallRect) / 20), rcSmallRect.right - (RECTWIDTH(&rcSmallRect) / 20), rcSmallRect.top + (RECTHEIGHT(&rcSmallRect) / 20)); SelectPen(hDCMem, hPen); Arc(hDCMem, rcSmallRect.left + 1, rcSmallRect.top + 1, rcSmallRect.right, rcSmallRect.bottom, rcSmallRect.right - (RECTWIDTH(&rcSmallRect) / 20), rcSmallRect.top + (RECTHEIGHT(&rcSmallRect) / 20), rcSmallRect.left + (RECTWIDTH(&rcSmallRect) / 20), rcSmallRect.bottom - (RECTHEIGHT(&rcSmallRect) / 20)); BitBlt(hDC, 0, 0, nRectWidth, nRectHeight, hDCMem, 0, 0, SRCCOPY); DeleteDC(hDCMem); DeleteBitmap(hBitmap); DeleteBrush(hBrush); DeletePen(hPen); DeletePen(hPen1); DeletePen(hPen2); DeletePen(hPen3); DeletePen(hPen4); DeletePen(hPen5); EndPaint(hWnd, &ps); } static L_VOID Angle_OnLButtonDown(HWND hWnd, L_BOOL bDoubleClick, L_INT nX, L_INT nY, L_UINT uKeyFlags) { LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hWnd, GWL_USERDATA); pAngleCtrl->bMove = TRUE; SetCapture(hWnd); Angle_OnMouseMove(hWnd, nX, nY, uKeyFlags); } static L_VOID Angle_OnLButtonUp(HWND hWnd, L_INT nX, L_INT nY, L_UINT uKeyFlags) { LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hWnd, GWL_USERDATA); if (pAngleCtrl->bMove) { pAngleCtrl->bMove = FALSE; ReleaseCapture(); if (pAngleCtrl->nApplyFilter == APPLY_ON_MOVE) return; switch(pAngleCtrl->nRange) { case FROM_180_TO_180: SetDlgItemInt(GetParent(hWnd), pAngleCtrl->nAttachedText, (pAngleCtrl->nAngle > 180 * pAngleCtrl->nPrec) ? -1 * (pAngleCtrl->nAngle - 360 * pAngleCtrl->nPrec) : pAngleCtrl->nAngle, FALSE); break; case FROM_0_TO_360: SetDlgItemInt(GetParent(hWnd), pAngleCtrl->nAttachedText, pAngleCtrl->nAngle, FALSE); break; case FROM_0_TO_8: SetDlgItemInt(GetParent(hWnd), pAngleCtrl->nAttachedText, pAngleCtrl->nAngle / 45, FALSE); break; } } } static L_VOID Angle_OnMouseMove(HWND hWnd, L_INT nX, L_INT nY, L_UINT uKeyFlags) { L_INT cxClient, cyClient; L_DOUBLE dTheta; RECT rcRect; LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hWnd, GWL_USERDATA); L_INT MaxAfterPrec; L_INT nAngle; GetClientRect(hWnd, &rcRect); if (pAngleCtrl->bMove) { MaxAfterPrec = 360 * pAngleCtrl->nPrec; cxClient = rcRect.right - rcRect.left; cyClient = rcRect.bottom - rcRect.top; dTheta = atan2((nY - (cyClient) / 2.0) , (nX - (cxClient) / 2.0)); pAngleCtrl->ptDir.x = (L_INT)((cxClient - 8) / 2 * cos(dTheta)) + (cxClient) / 2; pAngleCtrl->ptDir.y = (L_INT)((cyClient - 8) / 2 * sin(dTheta)) + (cyClient) / 2; pAngleCtrl->nAngle = (MaxAfterPrec - (L_INT)((180 * dTheta) / 3.14159)) % MaxAfterPrec; if (pAngleCtrl->nApplyFilter == APPLY_ON_UP) return; switch(pAngleCtrl->nRange) { case FROM_180_TO_180: nAngle = (pAngleCtrl->nAngle >= 180 * pAngleCtrl->nPrec) ? (pAngleCtrl->nAngle - MaxAfterPrec) : pAngleCtrl->nAngle; SetDlgItemInt(GetParent(hWnd), pAngleCtrl->nAttachedText, nAngle, TRUE); break; case FROM_0_TO_360: SetDlgItemInt(GetParent(hWnd), pAngleCtrl->nAttachedText, pAngleCtrl->nAngle, FALSE); break; case FROM_0_TO_8: nAngle = ((pAngleCtrl->nAngle + 23) / 45) % 8; SetDlgItemInt(GetParent(hWnd), pAngleCtrl->nAttachedText, nAngle, FALSE); break; } } } static L_VOID Angle_OnDestroy(HWND hWnd) { LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hWnd, GWL_USERDATA); SetWindowLong (hWnd, GWL_WNDPROC, (LONG) pAngleCtrl->wndProcOld); free (pAngleCtrl); } L_VOID DrawAngleControl(HWND hWnd, L_INT nAngle) { RECT rcRect; LPANGLCTRL pAngleCtrl = (LPANGLCTRL)GetWindowLong(hWnd, GWL_USERDATA); if (!pAngleCtrl) return; switch(pAngleCtrl->nRange) { case FROM_180_TO_180: if (nAngle < 0) nAngle = (nAngle + 360); break; case FROM_0_TO_8: nAngle *= 45; break; } nAngle /= pAngleCtrl->nPrec; pAngleCtrl->nAngle = nAngle; GetClientRect(hWnd, &rcRect); pAngleCtrl->ptDir.x = (L_INT)(((rcRect.right + rcRect.left - 8) / 2) * cos(nAngle * -3.14159 / 180.0) + (rcRect.right + rcRect.left) / 2 + 0.5); pAngleCtrl->ptDir.y = (L_INT)(((rcRect.bottom + rcRect.top - 8) / 2) * sin(nAngle * -3.14159 / 180.0) + (rcRect.bottom + rcRect.top ) / 2 + 0.5); InvalidateRect(hWnd, NULL, FALSE); } L_INT CreateAngleControl(HWND hAngleWnd, L_INT nAttachedText, L_INT nRange, L_INT nPrecision, L_INT nApplyFilter) { LPANGLCTRL pAngleCtrl; RECT rcRect; L_INT cxClient; L_INT cyClient; L_DOUBLE dTheta; POINT ptRect; pAngleCtrl = (LPANGLCTRL) malloc (sizeof(ANGLCTRL)); memset (pAngleCtrl, 0, sizeof(ANGLCTRL)); if (!pAngleCtrl) return FAILURE; GetWindowRect(hAngleWnd, &rcRect); ptRect.x = rcRect.left; ptRect.y = rcRect.top; ScreenToClient(GetParent(hAngleWnd), &ptRect); MoveWindow(hAngleWnd, ptRect.x, ptRect.y, max(RECTWIDTH(&rcRect), RECTHEIGHT(&rcRect)), max(RECTWIDTH(&rcRect), RECTHEIGHT(&rcRect)), TRUE); GetClientRect(hAngleWnd, &rcRect); pAngleCtrl->nAttachedText = nAttachedText; pAngleCtrl->nRange = nRange; pAngleCtrl->nPrec = nPrecision; pAngleCtrl->nApplyFilter = nApplyFilter; pAngleCtrl->nAngle = 0; pAngleCtrl->bMove = FALSE; cxClient = rcRect.right - rcRect.left - 8; cyClient = rcRect.bottom - rcRect.top - 8; dTheta = atan2(( ((rcRect.bottom + rcRect.top) >> 1) - (cyClient + 8)/2.0) , (rcRect.right - (cxClient + 8)/2.0)); pAngleCtrl->ptDir.x = (L_INT)(cxClient / 2 * cos(dTheta)) + ((cxClient + 8) >> 1); pAngleCtrl->ptDir.y = (L_INT)(cyClient / 2 * sin(dTheta)) + ((cyClient + 8) >> 1); pAngleCtrl->wndProcOld = (WNDPROC)GetWindowLong(hAngleWnd, GWL_WNDPROC); SetWindowLong(hAngleWnd, GWL_USERDATA, (LONG)pAngleCtrl); SetWindowLong(hAngleWnd, GWL_WNDPROC, (LONG)AngleWP); return SUCCESS; }