//Example1.c #include "Example1.h" #include "annotate.h" #include "utils.h" //************************************************************************************** // // Functions for Example1 // //************************************************************************************* L_VOID Example1_UpdateHandles(HANNOBJECT hObject) { L_UINT uCount; L_INT nRet; ANNPOINT AnnPoints[4]; L_AnnGetPoints(hObject, AnnPoints); nRet = L_AnnGetUserHandles(hObject, NULL, &uCount); if ((nRet == SUCCESS) && (uCount)) { //L_AnnDeleteHandle(hObject, -1); //delete all handles, and add them back Example1_AddUserHandles(hObject, AnnPoints); } } // Example1_AddUserHandles--adds handles for AP SPine Measure Annotation L_VOID Example1_AddUserHandles(HANNOBJECT hObject, pANNPOINT pAnnPoints) { ANNHANDLE AnnHandle; ANNHANDLE FourAnnHandles[4]; L_UINT uCount; L_UINT uFlags; L_AnnGetUserHandles(hObject, NULL, &uCount); if (uCount == 4) { uFlags = ANNHANDLE_LOCATION | ANNHANDLE_CONTAINER_COORDINATES; L_AnnGetUserHandles(hObject, FourAnnHandles, &uCount); FourAnnHandles[0].aptContainer.x = (pAnnPoints[0].x + pAnnPoints[1].x) / 2; FourAnnHandles[0].aptContainer.y = (pAnnPoints[0].y + pAnnPoints[1].y) / 2; FourAnnHandles[0].uFlags = uFlags; L_AnnChangeUserHandle(hObject, 0, FourAnnHandles + 0); FourAnnHandles[1].aptContainer.x = (pAnnPoints[1].x + pAnnPoints[2].x) / 2; FourAnnHandles[1].aptContainer.y = (pAnnPoints[1].y + pAnnPoints[2].y) / 2; FourAnnHandles[1].uFlags = uFlags; L_AnnChangeUserHandle(hObject, 1, FourAnnHandles + 1); FourAnnHandles[2].aptContainer.x = (pAnnPoints[2].x + pAnnPoints[3].x) / 2; FourAnnHandles[2].aptContainer.y = (pAnnPoints[2].y + pAnnPoints[3].y) / 2; FourAnnHandles[2].uFlags = uFlags; L_AnnChangeUserHandle(hObject, 2, FourAnnHandles + 2); FourAnnHandles[3].aptContainer.x = (pAnnPoints[3].x + pAnnPoints[0].x) / 2; FourAnnHandles[3].aptContainer.y = (pAnnPoints[3].y + pAnnPoints[0].y) / 2; FourAnnHandles[3].uFlags = uFlags; L_AnnChangeUserHandle(hObject, 3, FourAnnHandles + 3); } else { uFlags = ANNHANDLE_LOCATION | ANNHANDLE_CONTAINER_COORDINATES | ANNHANDLE_ID | ANNHANDLE_PEN_COLOR | ANNHANDLE_FILL_COLOR | ANNHANDLE_SHAPE; AnnHandle.uStructSize = sizeof(ANNHANDLE); AnnHandle.nShape = ANNHANDLE_SHAPE_CIRCLE; AnnHandle.crPen = RGB(0,0,0); AnnHandle.uFlags = uFlags; AnnHandle.aptContainer.x = (pAnnPoints[0].x + pAnnPoints[1].x) / 2; AnnHandle.aptContainer.y = (pAnnPoints[0].y + pAnnPoints[1].y) / 2; AnnHandle.crFill = RGB(0,0,0); AnnHandle.hCursor= LoadCursor(NULL, IDC_SIZEWE); AnnHandle.nID = HANDLE_ID_VERTICAL_LEFT; L_AnnAddUserHandle(hObject, &AnnHandle); AnnHandle.aptContainer.x = (pAnnPoints[1].x + pAnnPoints[2].x) / 2; AnnHandle.aptContainer.y = (pAnnPoints[1].y + pAnnPoints[2].y) / 2; AnnHandle.crFill = RGB(128,128,128); AnnHandle.hCursor= LoadCursor(NULL, IDC_SIZENS); AnnHandle.nID = HANDLE_ID_HORIZONTAL_BOTTOM; L_AnnAddUserHandle(hObject, &AnnHandle); AnnHandle.aptContainer.x = (pAnnPoints[2].x + pAnnPoints[3].x) / 2; AnnHandle.aptContainer.y = (pAnnPoints[2].y + pAnnPoints[3].y) / 2; AnnHandle.crFill = RGB(255,0,0); AnnHandle.hCursor= LoadCursor(NULL, IDC_SIZEWE); AnnHandle.nID = HANDLE_ID_VERTICAL_RIGHT; L_AnnAddUserHandle(hObject, &AnnHandle); AnnHandle.aptContainer.x = (pAnnPoints[3].x + pAnnPoints[0].x) / 2; AnnHandle.aptContainer.y = (pAnnPoints[3].y + pAnnPoints[0].y) / 2; AnnHandle.crFill = RGB(255,255,0); AnnHandle.hCursor= hCursorRotate; AnnHandle.nID = HANDLE_ID_HORIZONTAL_TOP; L_AnnAddUserHandle(hObject, &AnnHandle); } } // Example1_UpdateLine--draws the line for the AP SPine Measure annotation L_VOID Example1_UpdateLine(HANNOBJECT hRect, HANNOBJECT hLine) { POINT ptTop; POINT ptBottom; GetHandleInfo(hRect, HANDLE_ID_HORIZONTAL_TOP, &ptTop, NULL, NULL); GetHandleInfo(hRect, HANDLE_ID_HORIZONTAL_BOTTOM, &ptBottom, NULL, NULL); L_AnnDefine(hLine, &ptTop, ANNDEFINE_BEGINSET); L_AnnDefine(hLine, &ptBottom, ANNDEFINE_END); HideDefaultHandles(hLine); L_AnnSetVisible(hLine, TRUE, 0, NULL); AnnSetID(hLine, ANNTOOL_EXAMPLE1, 1); } // This handler gets called when there is a mouse move message on a user handle // There are four user handles that are processed differently // HANDLE_ID_VERTICAL_LEFT // HANDLE_ID_VERTICAL_RIGHT // These two both restrict the mouse cursor to a line parallel to the top of the rectangle, // even if the rectangle is rotated // HANDLE_ID_HORIZONTAL_BOTTOM // Restricts the mouse cursor to a line parallel to the side of the rectangle, // even if the rectangle is rotated // HANDLE_ID_HORIZONTAL_TOP // Rotates the rectangle around the bottom handle (HANDLE_ID_HORIZONTAL_BOTTOM) L_VOID Example1_Handle_LButtonDown(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { L_INT32 nCount; AnnGetNeighborObjects( pData->hObjectChange, pData->AnnObjectNeighbors, &nCount); AnnSortNeighborObjects(pData->hObjectChange, pData->AnnObjectNeighbors, nCount); switch (pData->nUserHandleID) { case HANDLE_ID_VERTICAL_LEFT: case HANDLE_ID_VERTICAL_RIGHT: L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_BEGINRESIZE); L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_BEGINMOVE); break; case HANDLE_ID_HORIZONTAL_BOTTOM: L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_BEGINRESIZE); L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_BEGINRESIZE); break; case HANDLE_ID_HORIZONTAL_TOP: { L_BOOL bRet; //top handle--make this rotate POINT ptLocation; bRet = GetHandleInfo(pData->hObjectChange, HANDLE_ID_HORIZONTAL_BOTTOM, &ptLocation, NULL, NULL); if (bRet) { L_AnnDefine(pData->hObjectChange, &ptLocation, ANNDEFINE_SETANCHORPOINT); L_AnnDefine(pData->AnnObjectNeighbors[1], &ptLocation, ANNDEFINE_SETANCHORPOINT); L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_BEGINROTATE); L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_BEGINROTATE); } } break; } } // This is part of the custom annotations demo (from example1.c) // This handler gets called when there is a mouse move message on a user handle // There are four user handles that are processed differently // HANDLE_ID_VERTICAL_LEFT // HANDLE_ID_VERTICAL_RIGHT // These two both restrict the mouse cursor to a line parallel to the top of the rectangle, // even if the rectangle is rotated // HANDLE_ID_HORIZONTAL_BOTTOM // Restricts the mouse cursor to a line parallel to the side of the rectangle, // even if the rectangle is rotated // HANDLE_ID_HORIZONTAL_TOP // Rotates the rectangle around the bottom handle (HANDLE_ID_HORIZONTAL_BOTTOM) L_VOID Example1_Handle_MouseMove(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { L_DOUBLE dAngle; ANNPOINT ptAnchor, ptMove; L_AnnGetRotateAngle(pData->hObjectChange, &dAngle); ptAnchor.x = pData->pt0.x; ptAnchor.y = pData->pt0.y; ptMove.x = pMousePos->pt.x; ptMove.y = pMousePos->pt.y; switch (pData->nUserHandleID) { case HANDLE_ID_VERTICAL_LEFT: case HANDLE_ID_VERTICAL_RIGHT: { L_DOUBLE dx, dy; POINT pt; L_AnnAdjustPoint(&ptAnchor, &ptMove, dAngle, ANNADJUST_HORIZONTAL); dx = (ptMove.x - ptAnchor.x)/2; dy = (ptMove.y - ptAnchor.y)/2; pt = pMousePos->pt; pt.x = (LONG)(ptAnchor.x + dx); pt.y = (LONG)(ptAnchor.y + dy); L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_APPEND); L_AnnDefine(pData->AnnObjectNeighbors[1], &pt, ANNDEFINE_APPEND); } break; case HANDLE_ID_HORIZONTAL_BOTTOM: L_AnnAdjustPoint(&ptAnchor, &ptMove, dAngle, ANNADJUST_VERTICAL); L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_APPEND); L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_APPEND); break; case HANDLE_ID_HORIZONTAL_TOP: L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_APPEND); L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_APPEND); break; } pMousePos->fUpdatePos = FALSE; if ( (pData->nUserHandleID == HANDLE_ID_VERTICAL_LEFT) || (pData->nUserHandleID == HANDLE_ID_VERTICAL_RIGHT) || (pData->nUserHandleID == HANDLE_ID_HORIZONTAL_TOP) || (pData->nUserHandleID == HANDLE_ID_HORIZONTAL_BOTTOM) ) { if (ISDIFFERENT(&ptMove,&pMousePos->pt)) { pMousePos->pt.x = ROUND(ptMove.x); pMousePos->pt.y = ROUND(ptMove.y); pMousePos->fUpdatePos = TRUE; } } } L_VOID Example1_Handle_LButtonUp(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_END); L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_END); Example1_UpdateHandles(pData->hObjectChange); Example1_UpdateLine(pData->hObjectChange, pData->AnnObjectNeighbors[1]); } //*************** Example1 Create functions L_VOID Example1_LButtonDown(HWND hWnd, LPCHILDDATA pData) { pData->ObjectExample1.bLineAdjust = FALSE; L_AnnAddUndoNode(pData->hAutomation); L_AnnCreateItem(pData->hContainer, ANNOBJECT_RECT, TRUE, &pData->ObjectExample1.hRect); AnnSetID(pData->ObjectExample1.hRect, ANNTOOL_EXAMPLE1, 0); L_AnnDefine(pData->ObjectExample1.hRect, &pData->ptStart, ANNDEFINE_BEGINSET); L_AnnCreateItem(pData->hContainer, ANNOBJECT_LINE, TRUE, &pData->ObjectExample1.hLine); AnnSetID(pData->ObjectExample1.hLine, ANNTOOL_EXAMPLE1, 1); pData->fCapture = TRUE; L_AnnDefine(pData->ObjectExample1.hLine, &pData->ptStart, ANNDEFINE_BEGINSET); L_AnnRestrictCursor(pData->hContainer, NULL, NULL, &pData->rcOldClip,TRUE); } L_VOID Example1_MouseMove(LPCHILDDATA pData) { L_AnnDefine(pData->ObjectExample1.hRect, &pData->ptMove, ANNDEFINE_APPEND); pData->ObjectExample1.bLineAdjust = TRUE; L_AnnDefine(pData->ObjectExample1.hLine, &pData->ptStart, ANNDEFINE_APPEND); pData->ObjectExample1.bLineAdjust = FALSE; } L_VOID Example1_LButtonUp(LPCHILDDATA pData, L_UINT uTool) { ANNPOINT AnnPoints[4]; HANNOBJECT hLine; // Destroy the line L_AnnDefine(pData->ObjectExample1.hLine, &pData->ptEnd, ANNDEFINE_END); L_AnnRemove(pData->ObjectExample1.hLine); L_AnnDestroy(pData->ObjectExample1.hLine, 0); // Finish creating the rectangle L_AnnDefine(pData->ObjectExample1.hRect, &pData->ptEnd, ANNDEFINE_END); HideDefaultHandles(pData->ObjectExample1.hRect); L_AnnGetPoints(pData->ObjectExample1.hRect, AnnPoints); Example1_AddUserHandles(pData->ObjectExample1.hRect, AnnPoints); L_AnnSetSelected(pData->ObjectExample1.hRect, TRUE, 0); // Create the line L_AnnCreateItem(pData->hContainer, ANNOBJECT_LINE, FALSE, &hLine); L_AnnSendToBack(hLine); Example1_UpdateLine(pData->ObjectExample1.hRect, hLine); L_AnnSetSelected(hLine, TRUE, 0); HideDefaultHandles(hLine); // set the default settings from the automation object, and group the objects L_AnnSetAutoDefaults(pData->hAutomation, pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE); L_AnnGroup(pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE, NULL); AnnSetID(pData->hRect, uTool, 0); DebugClipCursor(&pData->rcOldClip); } //********************************************************************** L_VOID Example1_Hilight(LPCHILDDATA pData, pANNHILIGHT pAnnHilight) { L_UINT uType; L_AnnGetType(pAnnHilight->hObject, &uType); if (pData->ObjectExample1.bLineAdjust && (uType == ANNOBJECT_LINE)) { if (pAnnHilight->bRemoveHilight) { pAnnHilight->ppts[0] = pData->ObjectExample1.ptPrevHilight[0]; pAnnHilight->ppts[1] = pData->ObjectExample1.ptPrevHilight[1]; } else { pAnnHilight->ppts[0].x = (pData->ptStart.x + pData->ptMove.x) / 2; pAnnHilight->ppts[1].x = pAnnHilight->ppts[0].x; pAnnHilight->ppts[0].y = pData->ptStart.y; pAnnHilight->ppts[1].y = pData->ptMove.y; } pData->ObjectExample1.ptPrevHilight[0] = pAnnHilight->ppts[0]; pData->ObjectExample1.ptPrevHilight[1] = pAnnHilight->ppts[1]; } }