/*[]=====================================================================[]*/ /*[] LEADTOOLS for Windows - Version 11 []*/ /*[] []*/ /*[] []*/ /*[] Copyright (c) 1991-2000 LEAD Technologies, Inc. []*/ /*[] All Rights Reserved. []*/ /*[]=====================================================================[]*/ #include /* required for all Windows applications */ #include #include #include #include #include "stdio.h" #include "TCHAR.h" #include "..\\..\\..\\include\\l_bitmap.h" /* LEADTOOLS main header file */ #include "..\\..\\..\\include\\l_error.h" /* LEADTOOLS error definition header file */ #include "types.h" #include "annotate.h" #include "handles.h" #include "example1.h" #include "SpineAngulated.h" #include "SpineMeasure.h" #include "SpineAnalysis.h" #include "SpineRough.h" #include "HipAnalysis.h" #include "RoughLateralSpine.h" #include "ForearmRough.h" #include "BoxCorner.h" #include "BoxSide.h" #include "BoxEightCorner.h" #include "WholeBodyAnalysis.h" #include "utils.h" #include "HipMeasure.h" #include "AnalysisLateralSpine.h" #define RECTWIDTH(lpRect) (((LPRECT) lpRect)->right - ((LPRECT) lpRect)->left) #define RECTHEIGHT(lpRect) (((LPRECT) lpRect)->bottom - ((LPRECT) lpRect)->top) #define CHILDCREATELPARAM(lpCreateStruct) (((LPMDICREATESTRUCT) ((lpCreateStruct)->lpCreateParams))->lParam) #define SETWNDDATA(hwnd, p) SetWindowLong(hwnd, 0, (LONG)(LPTSTR)(p)) #define GETWNDDATA(hwnd) ((LPTSTR) GetWindowLong(hwnd, 0)) #define DECLARECHILDDATA(hwnd, pData) LPCHILDDATA pData = (LPCHILDDATA) GETWNDDATA(hwnd) static void OpenDefaultBitmap(HWND hwnd); static L_VOID SetZoomFactor (HWND hwnd, int nZoom); #ifdef UNICODE //define for Unicode #define fullpath _wfullpath #else #define fullpath _fullpath #endif L_TCHAR szImageDir[_MAX_PATH]; typedef struct tagCREATEDATA { LPTSTR pszTitle; pBITMAPHANDLE pBitmap; HANNOBJECT hObject; } CREATEDATA, L_FAR * LPCREATEDATA; typedef struct _RANGEPARM { L_TCHAR szTitle[32]; L_TCHAR szLabel[32]; int nValue; int nMin; int nMax; int nStep; int nPage; } RANGEPARM, FAR * LPRANGEPARM; BITMAPHANDLE BitmapPoint; HINSTANCE hInst; HWND hwndClient; HWND hwndFrame; HWND hwndToolBar; int nAnnObject = IDM_TOOLSELECT; int nAnnUserMode = IDM_USERDESIGN; HCURSOR hCursorRotate; HCURSOR hCursorHorizontalResize; TCHAR szBitmapFile[L_MAXPATH]=TEXT(""); TCHAR szAnnFile[L_MAXPATH]=TEXT(""); LOADFILEOPTION LoadFileOption; SAVEFILEOPTION SaveFileOption; static L_VOID SaveBitmap(HWND hWnd); static int DoDialogBoxParam(int nDialog, HWND hwnd, DLGPROC pfnDialog, LPARAM lParam); static int GetHyperlink (HWND hWnd, HANNOBJECT hObject, LPCHILDDATA pData); L_BOOL ExtractCommandData ( ); #define WM_USERMSG (WM_USER + 1) #define HANDLE_WM_USERMSG(hwnd, wParam, lParam, fn) \ (LRESULT)(DWORD)(fn)(hwnd, (int) wParam, lParam) int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; HBITMAP hBitmapPoint=NULL; L_VOID *pBits; LPBITMAPINFOHEADER pBitmapInfoHeader = NULL; L_INT nColors; UNLOCKSUPPORT(); L_DlgInit(DLG_INIT_COLOR); if (L_IsSupportLocked(L_SUPPORT_DOCUMENT)) { MessageBox(NULL, TEXT("Annotation Support Must Be Unlocked to Run this Demo!"), TEXT("Warning"), MB_OK | MB_ICONWARNING); return FALSE; } ExtractCommandData ( ); // Load the Hip Measure bitmap for the point annotation hBitmapPoint = LoadResource( hInstance, // module handle FindResource(hInstance, MAKEINTRESOURCE(IDB_POINT), RT_BITMAP ) ); pBitmapInfoHeader = (LPBITMAPINFOHEADER)LockResource(hBitmapPoint); if (pBitmapInfoHeader->biCompression == BI_BITFIELDS) nColors = 3; else if(pBitmapInfoHeader->biBitCount > 8) nColors = 0; else if (pBitmapInfoHeader->biClrUsed) nColors = pBitmapInfoHeader->biClrUsed; else nColors = 1<biBitCount; pBits = (L_UCHAR *)pBitmapInfoHeader + pBitmapInfoHeader->biSize + nColors * sizeof(RGBQUAD); L_ConvertFromDIB(&BitmapPoint, sizeof(BITMAPHANDLE),(BITMAPINFO *)pBitmapInfoHeader, pBits); L_GetDefaultLoadFileOption(&LoadFileOption, sizeof(LOADFILEOPTION)); L_GetDefaultSaveFileOption(&SaveFileOption, sizeof(SAVEFILEOPTION)); hInst = hInstance; if (!hPrevInstance && !InitApplication ()) return (FALSE); if (!InitInstance (nCmdShow)) return (FALSE); while (GetMessage (&msg, NULL, 0, 0)) { if (!TranslateMDISysAccel (hwndClient, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } return(msg.wParam); } BOOL InitApplication (void) { WNDCLASS wndClass; BOOL fRegistered; wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = (WNDPROC) FrameWndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInst; wndClass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_MAIN)); wndClass.hCursor = LoadCursor (NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject (GRAY_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = SZ_FRAMECLASS; fRegistered = RegisterClass (&wndClass); if(!fRegistered) return(FALSE); wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndClass.lpfnWndProc = (WNDPROC) ChildWndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 4; wndClass.hInstance = hInst; wndClass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_MAIN)); wndClass.hCursor = LoadCursor (NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject (GRAY_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = SZ_CHILDCLASS; fRegistered = RegisterClass (&wndClass); if(!fRegistered) return(FALSE); return(TRUE); } BOOL InitInstance (int nCmdShow) { L_GetDefaultLoadFileOption(&LoadFileOption, sizeof(LOADFILEOPTION)); L_GetDefaultSaveFileOption(&SaveFileOption, sizeof(SAVEFILEOPTION)); hCursorRotate = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR_ROTATE)); hCursorHorizontalResize = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR_HORIZONTAL_RESIZE)); hwndFrame = CreateWindow (SZ_FRAMECLASS, TEXT("LEADTOOLS Custom Annotation Example"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_MAXIMIZE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, LoadMenu (hInst, MAKEINTRESOURCE (MENU_MAIN)), hInst, NULL); if (hwndFrame == NULL) return (FALSE); ShowWindow (hwndFrame, nCmdShow); UpdateWindow (hwndFrame); return (TRUE); } #define ISTIF(nFormat) \ ((nFormat) == FILE_JTIF || \ (nFormat) == FILE_LEAD2JTIF || \ (nFormat) == FILE_LEAD1JTIF || \ (nFormat) == FILE_TIFLZW || \ (nFormat) == FILE_TIFLZW_CMYK || \ (nFormat) == FILE_TIFLZW_YCC || \ (nFormat) == FILE_TIF || \ (nFormat) == FILE_TIF_CMYK || \ (nFormat) == FILE_TIF_YCC || \ (nFormat) == FILE_TIF_PACKBITS || \ (nFormat) == FILE_TIF_PACKBITS_CMYK ||\ (nFormat) == FILE_TIF_PACKBITS_YCC || \ (nFormat) == FILE_CCITT || \ (nFormat) == FILE_CCITT_GROUP3_1DIM ||\ (nFormat) == FILE_CCITT_GROUP3_2DIM ||\ (nFormat) == FILE_CCITT_GROUP4 || \ (nFormat) == FILE_TIF_CMP || \ (nFormat) == FILE_TIF_JBIG) void GetAnnFile(LPTSTR pDest, LPTSTR pSource, L_UINT nPage, L_INT nFormat) { LPTSTR p; L_UINT16 uType; L_UINT32 uCount; L_INT nOldPage; nOldPage = LoadFileOption.PageNumber; LoadFileOption.PageNumber = nPage; if(nFormat < 0 && L_ReadFileTag(pSource, ANNTAG_TIFF, &uType, &uCount, NULL, &LoadFileOption) > 0 || ISTIF(nFormat)) /* the file has annotation data! */ lstrcpy(pDest, pSource); else { /* else look for a .ANN file */ lstrcpy(pDest, pSource); p = _tcspbrk(pDest, TEXT(".")); if(!p) p = _tcschr(pDest, '\0'); lstrcpy(p, TEXT(".ann")); } LoadFileOption.PageNumber = nOldPage; } static OPENFILENAME OpenFileName; static OPENDLGPARAMS FOParm; /*--------------------------------------------------------------------------+ | Function :CleanOpenDlgParam | Desc :Clean File open Param structuer | Return : | Notes : +--------------------------------------------------------------------------*/ L_VOID CleanOpenDlgParam(LPOPENDLGPARAMS pFOParam) { int i=0; if(pFOParam!=NULL && pFOParam->pFileData!= NULL ) { for(i=0; i < pFOParam->nNumOfFiles; ++i ) { if(pFOParam->pFileData[i].pBitmap != NULL) { L_FreeBitmap(pFOParam->pFileData[i].pBitmap); GlobalFreePtr(pFOParam->pFileData[i].pBitmap); } if(pFOParam->pFileData[i].pThumbnail != NULL) { L_FreeBitmap(pFOParam->pFileData[i].pThumbnail); GlobalFreePtr(pFOParam->pFileData[i].pThumbnail); } if(pFOParam->pFileData[i].pFileInfo != NULL) { GlobalFreePtr(pFOParam->pFileData[i].pFileInfo); } } GlobalFreePtr(pFOParam->pFileData); pFOParam->pFileData =NULL; pFOParam->nNumOfFiles = 0; } } BOOL GetFileName(HWND hwnd, LPTSTR pszTitle, LPTSTR pszFilter, LPTSTR pszFile) { L_INT nRet; L_TCHAR szFile[_MAX_PATH]=TEXT(""); _fmemset(&FOParm, 0, sizeof(OPENDLGPARAMS)); FOParm.uStructSize = sizeof (OPENDLGPARAMS); FOParm.uStructSize = sizeof(OPENDLGPARAMS); FOParm.bShowLoadOptions = FALSE; FOParm.bPreviewEnabled = TRUE; FOParm.uDlgFlags = DLG_OPEN_SHOW_PROGRESSIVE | DLG_OPEN_SHOW_MULTIPAGE | DLG_OPEN_SHOW_LOADROTATED | DLG_OPEN_SHOW_LOADCOMPRESSED | DLG_OPEN_SHOW_FILEINFO | DLG_OPEN_SHOW_PREVIEW | DLG_OPEN_SHOW_DELPAGE | DLG_OPEN_SHOW_LOADOPTIONS | DLG_OPEN_SHOW_RASTEROPTIONS ; if(!OpenFileName.lStructSize) { OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.lpstrFilter = pszFilter; OpenFileName.lpstrCustomFilter = NULL; OpenFileName.nMaxCustFilter = 0; OpenFileName.nFilterIndex = 0; OpenFileName.lpstrFile = szFile; OpenFileName.nMaxFile = sizeof(szFile); OpenFileName.lpstrInitialDir = szImageDir; OpenFileName.lpstrTitle = TEXT("Open a File"); OpenFileName.nFileOffset = 0; OpenFileName.nFileExtension = 0; OpenFileName.lpstrDefExt = NULL; OpenFileName.Flags = 0; } nRet = L_DlgOpen( hwnd, &OpenFileName, &FOParm); if (nRet == SUCCESS_DLG_OK) { SetPageNumber(FOParm.pFileData->nPageNumber); lstrcpy (pszFile, FOParm.pFileData[ 0 ].szFileName); CleanOpenDlgParam(&FOParm); return(TRUE); } else return(FALSE); } static L_BOOL ConvertToBitmap(LPBITMAPINFO pbm, pBITMAPHANDLE pBitmap) { L_CHAR L_FAR*pBits; L_INT nPaletteEntries; if(!pbm) return FALSE; if(pbm->bmiHeader.biBitCount <= 8) nPaletteEntries = (L_INT)(pbm->bmiHeader.biClrUsed ? pbm->bmiHeader.biClrUsed : (1 << pbm->bmiHeader.biBitCount) ); else #ifdef WIN32 nPaletteEntries = (pbm->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0; #else nPaletteEntries = 0; #endif pBits = (L_CHAR L_FAR*)(&pbm->bmiColors[nPaletteEntries]); return (L_ConvertFromDIB(pBitmap, sizeof(BITMAPHANDLE), pbm, pBits) == SUCCESS); } static L_BOOL LoadAsBitmap (HINSTANCE hInstance, LPCTSTR pszName, pBITMAPHANDLE pBitmap) { HRSRC hrsrc; HGLOBAL hdib; L_BOOL bRet; L_InitBitmap(pBitmap, sizeof(BITMAPHANDLE), 1, 1, 1); hrsrc = FindResource(hInstance, pszName, RT_BITMAP); if(!hrsrc) return FALSE; hdib = LoadResource(hInstance, hrsrc); if(!hdib) return FALSE; bRet = ConvertToBitmap((LPBITMAPINFO)LockResource(hdib), pBitmap); FreeResource(hdib); return bRet; } static void AddButton(HWND hwnd, pANNBUTTON pButton, L_INT nID, L_TCHAR *pszText, L_UINT uToolId) { pBITMAPHANDLE pUserBitmap = NULL; pUserBitmap = (pBITMAPHANDLE)malloc(sizeof(BITMAPHANDLE)); if(LoadAsBitmap(hInst, MAKEINTRESOURCE(nID), pUserBitmap)) { pButton->uStructSize = sizeof(ANNBUTTON); pButton->uBitmapStructSize = sizeof(BITMAPHANDLE); pButton->uFlags = 0; // I will pass the string and there is only one tool pButton->uTool = uToolId; // make sure the bitmap is TOOLBARIMAGECX x TOOLBARIMAGECY L_SizeBitmap(pUserBitmap, TOOLBARIMAGECX, TOOLBARIMAGECY, 0); pButton->pBitmapUp = pButton->pBitmapDown = pUserBitmap; pButton->nToolTipTextID = -1; pButton->pToolTipText = pszText; } } static L_VOID HideToolBarTools(HWND hwndToolBar) { L_INT i; L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_LINE , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_RECT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_ELLIPSE , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_POLYLINE , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_POLYGON , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_POINTER , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_FREEHAND , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_HILITE , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_REDACT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_TEXT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_NOTE , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_STAMP , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_BUTTON , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_HOTSPOT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_AUDIO , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_RULER , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_CROSSPRODUCT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_POINT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_PROTRACTOR , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_VIDEO , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_PUSHPIN , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_FREEHANDHOTSPOT, FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_CURVE , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_CURVECLOSED , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_ENCRYPT , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_TEXTPOINTER , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_POLYRULER , FALSE); L_AnnSetToolBarButtonVisible(hwndToolBar, ANNTOOL_RTF , FALSE); for (i=ANNTOOL_STAMP_FIRST; i<=ANNTOOL_STAMP_LAST; i++) L_AnnSetToolBarButtonVisible(hwndToolBar, i, FALSE); } #ifdef HIP_ANALYSIS #define USER_DEFINED_COUNT 16 #else #define USER_DEFINED_COUNT 14 #endif static HWND MyCreateToolBar(HWND hwnd) { L_INT i; L_UINT uButtons; pANNBUTTON pButtons; L_INT nSize; // create the window hidden, since I want to modify its buttons if(L_AnnCreateToolBar(hwnd, NULL, ANNTOOLALIGN_RIGHT | ANNTOOLALIGN_TOP, FALSE, &hwnd, 0, NULL) != SUCCESS) return NULL; if(L_AnnGetToolBarButtons(hwnd, NULL, sizeof(ANNBUTTON), &uButtons) != SUCCESS) return NULL; nSize = (uButtons + USER_DEFINED_COUNT) * sizeof(ANNBUTTON); pButtons = (pANNBUTTON)malloc(nSize); memset(pButtons, 0, nSize); if(pButtons && L_AnnGetToolBarButtons(hwnd, pButtons, sizeof(ANNBUTTON), &uButtons) != SUCCESS) return NULL; i=0; AddButton(hwnd, pButtons + uButtons + i++, IDB_EXAMPLE1, TEXT("Example1"), ANNTOOL_EXAMPLE1); AddButton(hwnd, pButtons + uButtons + i++, IDB_AP_SPINE_MEASURE, TEXT("AP Spine Measure"), ANNTOOL_AP_SPINE_MEASURE); AddButton(hwnd, pButtons + uButtons + i++, IDB_ROUGH_AP_SPINE, TEXT("AP Spine Rough"), ANNTOOL_AP_SPINE_ROUGH); AddButton(hwnd, pButtons + uButtons + i++, IDB_ANALYSIS_AP_SPINE, TEXT("AP Spine Analysis"), ANNTOOL_AP_SPINE_ANALYSIS); AddButton(hwnd, pButtons + uButtons + i++, IDB_ANGULATED_AP_SPINE, TEXT("AP Angulated Spine"), ANNTOOL_AP_SPINE_ANGULATED); #ifdef HIP_ANALYSIS AddButton(hwnd, pButtons + uButtons + i++, IDB_ANALYSIS_AP_HIP1, TEXT("AP Hip Analysis 1"), ANNTOOL_HIP_ANALYSIS1); AddButton(hwnd, pButtons + uButtons + i++, IDB_ANALYSIS_AP_HIP2, TEXT("AP Hip Analysis 2"), ANNTOOL_HIP_ANALYSIS2); #endif AddButton(hwnd, pButtons + uButtons + i++, IDB_ROUGH_LATERAL_SPINE, TEXT("Rough Lateral Spine"), ANNTOOL_ROUGH_LATERAL_SPINE); AddButton(hwnd, pButtons + uButtons + i++, IDB_ANALYSIS_LATERAL_SPINE, TEXT("Analysis Lateral Spine"), ANNTOOL_ANALYSIS_LATERAL_SPINE); AddButton(hwnd, pButtons + uButtons + i++, IDB_HIP_MEASURE_RIGHT, TEXT("Hip Measure (right)"), ANNTOOL_HIP_MEASURE_RIGHT); AddButton(hwnd, pButtons + uButtons + i++, IDB_HIP_MEASURE_LEFT, TEXT("Hip Measure (left)"), ANNTOOL_HIP_MEASURE_LEFT); AddButton(hwnd, pButtons + uButtons + i++, IDB_FOREARM_ROUGH, TEXT("Forearm Rough"), ANNTOOL_FOREARM_ROUGH); AddButton(hwnd, pButtons + uButtons + i++, IDB_WHOLE_BODY_ANALYSIS, TEXT("Whole Body Analysis"), ANNTOOL_WHOLE_BODY_ANALYSIS); AddButton(hwnd, pButtons + uButtons + i++, IDB_BOX_CORNER, TEXT("Box Corner"), ANNTOOL_BOX_CORNER); AddButton(hwnd, pButtons + uButtons + i++, IDB_BOX_SIDE, TEXT("Box Side"), ANNTOOL_BOX_SIDE); AddButton(hwnd, pButtons + uButtons + i++, IDB_BOX_EIGHT_CORNER, TEXT("Box Eight Corner"), ANNTOOL_BOX_EIGHT_CORNER); // Change the buttons L_AnnSetToolBarButtons(hwnd, pButtons, uButtons+USER_DEFINED_COUNT); // free the memory allocated by L_AnnGetToolBarButtons L_AnnFreeToolBarButtons(pButtons, uButtons); // free the pButtons buffer. L_AnnFreeToolBarButtons does not free it, since // the buffer was not allocated by it for (i=0; ihContainer, (nAnnUserMode == IDM_USERDESIGN) ? ANNUSER_DESIGN : ANNUSER_RUN); } return(TRUE); } static HWND CreateChildWindow (LPTSTR pszTitle, pBITMAPHANDLE pBitmap, HANNOBJECT hObject) { MDICREATESTRUCT mdiCreateStruct; CREATEDATA CreateData; HWND hwndChild; CreateData.pszTitle = pszTitle; CreateData.pBitmap = pBitmap; CreateData.hObject = hObject; mdiCreateStruct.szClass = SZ_CHILDCLASS; mdiCreateStruct.szTitle = pszTitle; mdiCreateStruct.hOwner = hInst; mdiCreateStruct.x = CW_USEDEFAULT; mdiCreateStruct.y = CW_USEDEFAULT; mdiCreateStruct.cx = CW_USEDEFAULT; mdiCreateStruct.cy = CW_USEDEFAULT; mdiCreateStruct.style = MDIS_ALLCHILDSTYLES; mdiCreateStruct.lParam = (LPARAM) (LPCREATEDATA) & CreateData; hwndChild = FORWARD_WM_MDICREATE (hwndClient, (LPMDICREATESTRUCT) & mdiCreateStruct, SendMessage); return(hwndChild); } static void OpenBitmap(HWND hwnd) { int nRet; BITMAPHANDLE Bitmap; HANNOBJECT hObject; pLOADFILEOPTION pLoadFileOption = NULL; L_BOOL pfReady; L_AnnClipboardReady(&pfReady); if(GetFileName(hwnd, TEXT("Open File"), NULL, szBitmapFile)) { nRet = L_LoadBitmap (szBitmapFile, &Bitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, &LoadFileOption, NULL); if(nRet == SUCCESS) { /* if the resolution is 0, default to 150 */ Bitmap.XResolution = Bitmap.XResolution ? Bitmap.XResolution : 150; Bitmap.YResolution = Bitmap.YResolution ? Bitmap.YResolution : 150; hObject = NULL; GetAnnFile(szAnnFile, szBitmapFile, 1, -1); pLoadFileOption = LoadFileOption.PageNumber ? &LoadFileOption : NULL; L_AnnLoad(szAnnFile, &hObject, pLoadFileOption); CreateChildWindow(szBitmapFile, &Bitmap, hObject); } else { if(nRet == ERROR_PDF_BAD_INITIALIZATION_FILES) { if( IDYES == MessageBox ( hwnd,TEXT("LEADTOOLS PDF plugin is not found, do you want to download the plugin now?"), TEXT("Open"),MB_ICONEXCLAMATION | MB_YESNO)) { ShellExecute(hwnd, TEXT("open"), TEXT("http://www.leadtools.com/ReleaseDownloads/v14/LEADTOOLSPDFRuntime.exe"), NULL, NULL, SW_SHOWNORMAL); } } } } else { FORWARD_WM_QUERYNEWPALETTE (hwnd, SendMessage); } } static void OpenDefaultBitmap(HWND hwnd) { int nRet; BITMAPHANDLE Bitmap; HANNOBJECT hObject; pLOADFILEOPTION pLoadFileOption = NULL; HWND hwndChild; L_BOOL pfReady; L_AnnClipboardReady(&pfReady); nRet = L_CreateBitmap( &Bitmap, sizeof(BITMAPHANDLE), TYPE_CONV, 800, 500, 24, ORDER_BGR, 0, TOP_LEFT, NULL, 0); if(nRet == SUCCESS) { L_FillBitmap(&Bitmap, RGB(200,200,200)); hObject = NULL; hwndChild = CreateChildWindow(TEXT("Temp"), &Bitmap, hObject); ShowWindow(hwndChild, SW_SHOWMAXIMIZED); SetZoomFactor (hwndChild, 100); } } static void PasteBitmap(HWND hwnd) { int nRet; BITMAPHANDLE Bitmap; HANNOBJECT hObject; L_BOOL pfReady; nRet = L_CopyFromClipboard (hwnd, &Bitmap, sizeof(BITMAPHANDLE)); if(nRet == SUCCESS ) { hObject = NULL; L_AnnClipboardReady(&pfReady); if( pfReady == TRUE ) L_AnnCopyFromClipboard(hwnd, &hObject); CreateChildWindow(szBitmapFile, &Bitmap, hObject); } } static void Frame_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { FARPROC lpfn; HWND hwndChild; switch(id) { case IDM_USERDESIGN: case IDM_USERRUN: CheckMenuItem(GetMenu(hwndFrame), nAnnUserMode, MF_UNCHECKED); nAnnUserMode = id; CheckMenuItem(GetMenu(hwndFrame), nAnnUserMode, MF_CHECKED); ShowWindow(hwndToolBar, (nAnnUserMode == IDM_USERDESIGN) ? SW_NORMAL : SW_HIDE); EnableMenuItem( GetSubMenu(GetMenu(hwndFrame),MENU_EDIT_POS), MENU_TOOL_POS, MF_BYPOSITION | ((nAnnUserMode == IDM_USERDESIGN) ? MF_ENABLED : MF_GRAYED)); EnableMenuItem(GetMenu(hwndFrame),IDM_ANNOTATIONTOOLBAR,((nAnnUserMode == IDM_USERDESIGN) ? MF_ENABLED : MF_GRAYED)); lpfn = MakeProcInstance((FARPROC) SetUserMode, hInst); EnumChildWindows(hwndClient, (WNDENUMPROC) lpfn, 0); FreeProcInstance(lpfn); break; case IDM_OPEN: OpenBitmap(hwnd); break; case IDM_CASCADE: FORWARD_WM_MDICASCADE(hwndClient, 0, SendMessage); break; case IDM_TILE: FORWARD_WM_MDITILE(hwndClient, MDITILE_HORIZONTAL, SendMessage); break; case IDM_ARRANGE: FORWARD_WM_MDIICONARRANGE(hwndClient, SendMessage); break; case IDM_EXIT: FORWARD_WM_CLOSE(hwnd, SendMessage); break; case IDM_CLOSEALL: lpfn = MakeProcInstance((FARPROC) CloseAll, hInst); EnumChildWindows(hwndClient, (WNDENUMPROC) lpfn, 0); FreeProcInstance(lpfn); break; case IDM_ANNOTATIONTOOLBAR: if( IsWindow(hwndToolBar) ) DestroyWindow(hwndToolBar); else { hwndToolBar = MyCreateToolBar(hwnd); CheckMenuItem(GetMenu(hwnd), IDM_ANNOTATIONTOOLBAR, MF_CHECKED); } break; case IDM_ABOUT: DoDialogBoxParam(IDD_ABOUT, hwnd, (DLGPROC) AboutDlgProc, 0); break; default: hwndChild = FORWARD_WM_MDIGETACTIVE(hwndClient, SendMessage); if (IsWindow (hwndChild)) FORWARD_WM_COMMAND(hwndChild, id, hwndCtl, codeNotify, SendMessage); #ifdef WIN32 DefFrameProc(hwnd, hwndClient, WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl)); #else DefFrameProc(hwnd, hwndClient, WM_COMMAND, (WPARAM) (int) (id), MAKELPARAM ((UINT) (hwndCtl), (codeNotify))); #endif break; } } BOOL CALLBACK PaletteChangedAll (HWND hwnd, LPARAM lParam) { if (GetWindow (hwnd, GW_OWNER)) return(TRUE); FORWARD_WM_PALETTECHANGED (hwnd, (HWND) (UINT) (lParam), SendMessage); return(TRUE); } static void Frame_OnPaletteChanged(HWND hwnd, HWND hwndPaletteChange) { FARPROC lpfn = MakeProcInstance ((FARPROC) PaletteChangedAll, hInst); EnumChildWindows (hwndClient, (WNDENUMPROC) lpfn, (LPARAM) (UINT) hwndPaletteChange); FreeProcInstance (lpfn); return; } static BOOL Frame_OnQueryNewPalette(HWND hwnd) { HWND hwndChild = FORWARD_WM_MDIGETACTIVE (hwndClient, SendMessage); // if there is no active window, pass the message to the toolbar window if(!IsWindow (hwndChild)) hwndChild = hwndToolBar; if (hwndChild) FORWARD_WM_QUERYNEWPALETTE (hwndChild, SendMessage); return(TRUE); } VOID Frame_OnPaletteChanging(HWND hWnd, HWND hWndPaletteChange) { Frame_OnPaletteChanged (hWnd, hWndPaletteChange); } VOID Frame_SysColorChange(HWND hwnd) { Frame_OnQueryNewPalette (hwnd); } static void Frame_OnClose(HWND hwnd) { FORWARD_WM_COMMAND (hwnd, IDM_CLOSEALL, 0, 0, SendMessage); DestroyWindow (hwnd); } static void Frame_OnDestroy(HWND hwnd) { L_DlgFree(); PostQuitMessage (0); } static void ToolChecked(HWND hwnd, UINT uTool) { HWND hwndChild; hwndChild = FORWARD_WM_MDIGETACTIVE(hwndClient, SendMessage); if(IsWindow(hwndChild)) { DECLARECHILDDATA(hwndChild, pData); L_AnnSetTool(pData->hAutomation, uTool); } } static LRESULT Frame_OnLtAnnEvent(HWND hwnd, int id, LPARAM lParam) { switch(id) { case LTANNEVENT_TOOLDESTROY: hwndToolBar = NULL; CheckMenuItem(GetMenu(hwnd),IDM_ANNOTATIONTOOLBAR,MF_UNCHECKED); break; case LTANNEVENT_TOOLCHECKED: ToolChecked(hwnd, (UINT) lParam); break; } return(0); } void Frame_OnInitMenuPopup (HWND hwnd, HMENU hMenu, L_INT item, BOOL fSystemMenu) { HWND hwndChild = FORWARD_WM_MDIGETACTIVE(hwndClient, SendMessage); HANNOBJECT hObject=NULL; DECLARECHILDDATA(hwndChild, pData); BOOL fHasChild = IsWindow(hwndChild); L_UINT uSelectCount = 0; L_BOOL bSelected; if (fHasChild) { L_AnnGetItem(pData->hContainer, &hObject); L_AnnGetSelectCount(pData->hContainer, &uSelectCount); bSelected = uSelectCount > 0; } if(!fSystemMenu && GetSubMenu (GetMenu (hwndFrame), item) == hMenu) { if (fHasChild) { if (IsZoomed (hwndChild)) item--; } switch (item) { case MENU_FILE_POS: EnableMenuItem(hMenu, IDM_SAVEAS, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_PRINT, fHasChild ? MF_ENABLED : MF_GRAYED); break; case MENU_EDIT_POS: EnableMenuItem(hMenu, IDM_ANNENUMERATENODES, (fHasChild && bSelected)? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_ANNBREAKALLGROUPS, (fHasChild && (hObject != 0))? MF_ENABLED : MF_GRAYED); break; case MENU_VIEW_POS: EnableMenuItem(hMenu, IDM_NORMAL, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_ZOOM, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_FITIMAGE, fHasChild ? MF_ENABLED : MF_GRAYED); CheckMenuItem (hMenu, IDM_NORMAL, (fHasChild && !pData->fFitImage && pData->nZoom == 100) ? MF_CHECKED: MF_UNCHECKED); CheckMenuItem (hMenu, IDM_ZOOM, (fHasChild && !pData->fFitImage && pData->nZoom != 100) ? MF_CHECKED: MF_UNCHECKED); CheckMenuItem (hMenu, IDM_FITIMAGE, (fHasChild && pData->fFitImage) ? MF_CHECKED: MF_UNCHECKED); break; case MENU_WINDOW_POS: EnableMenuItem(hMenu, IDM_CASCADE, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_TILE, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_ARRANGE, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_CLOSEALL, fHasChild ? MF_ENABLED : MF_GRAYED); } } return; } LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG (hwnd, WM_CREATE, Frame_OnCreate); HANDLE_MSG (hwnd, WM_PALETTECHANGED, Frame_OnPaletteChanged); HANDLE_MSG (hwnd, WM_QUERYNEWPALETTE, Frame_OnQueryNewPalette); HANDLE_MSG (hwnd, WM_PALETTEISCHANGING, Frame_OnPaletteChanging); HANDLE_MSG (hwnd, WM_SYSCOLORCHANGE, Frame_SysColorChange); HANDLE_MSG (hwnd, WM_DESTROY, Frame_OnDestroy); HANDLE_MSG (hwnd, WM_COMMAND, Frame_OnCommand); HANDLE_MSG (hwnd, WM_CLOSE, Frame_OnClose); HANDLE_MSG (hwnd, WM_LTANNEVENT, Frame_OnLtAnnEvent); HANDLE_MSG (hwnd, WM_INITMENUPOPUP, Frame_OnInitMenuPopup); } return(DefFrameProc (hwnd, hwndClient, msg, wParam, lParam)); } static BOOL Child_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct) { LPCREATEDATA pCreateData; LPCHILDDATA pData; ANNRECT rc; pCreateData = (LPCREATEDATA) CHILDCREATELPARAM (lpCreateStruct); pData = (LPCHILDDATA) GlobalAllocPtr (GHND, sizeof (CHILDDATA)); SETWNDDATA (hwnd, pData); if(!pData) return(FALSE); pData->Bitmap = *pCreateData->pBitmap; SetRect(&pData->rcView, 0, 0, BITMAPWIDTH(&pData->Bitmap), BITMAPHEIGHT(&pData->Bitmap)); pData->nZoom = 100; if(pCreateData->hObject) { pData->hContainer = pCreateData->hObject; L_AnnSetWnd(pData->hContainer, hwnd); } else { rc.left = (L_DOUBLE) pData->rcView.left; rc.top = (L_DOUBLE) pData->rcView.top; rc.right = (L_DOUBLE) pData->rcView.right; rc.bottom = (L_DOUBLE) pData->rcView.bottom; L_AnnCreateContainer(hwnd, &rc, TRUE, &pData->hContainer); } L_AnnSetUserMode(pData->hContainer, (nAnnUserMode == IDM_USERDESIGN) ? ANNUSER_DESIGN : ANNUSER_RUN); L_AnnCreate(ANNOBJECT_AUTOMATION, &pData->hAutomation); L_AnnSetAutoContainer(pData->hAutomation, pData->hContainer); L_AnnSetActiveState(pData->hAutomation, ANNACTIVE_ENABLED); { HDC hdc = GetDC(NULL); L_AnnSetDpiX(pData->hAutomation, (L_DOUBLE) GetDeviceCaps(hdc,LOGPIXELSX), ANNFLAG_NOINVALIDATE); L_AnnSetDpiY(pData->hAutomation, (L_DOUBLE) GetDeviceCaps(hdc,LOGPIXELSY), ANNFLAG_NOINVALIDATE); ReleaseDC(NULL, hdc); } L_AnnSetUndoDepth(pData->hAutomation, 10); L_AnnSetHyperlinkMenuEnable(pData->hAutomation, TRUE, ANNFLAG_NOINVALIDATE); L_AnnSetBitmapDpiX(pData->hAutomation, (L_DOUBLE) pData->Bitmap.XResolution, ANNFLAG_NOINVALIDATE); L_AnnSetBitmapDpiY(pData->hAutomation, (L_DOUBLE) pData->Bitmap.YResolution, ANNFLAG_NOINVALIDATE); L_AnnSetBitmapDpiX(pData->hContainer, (L_DOUBLE) pData->Bitmap.XResolution, ANNFLAG_RECURSE|ANNFLAG_NOINVALIDATE); L_AnnSetBitmapDpiY(pData->hContainer, (L_DOUBLE) pData->Bitmap.YResolution, ANNFLAG_RECURSE|ANNFLAG_NOINVALIDATE); L_AnnSetAutoOptions(pData->hAutomation, ANNAUTO_TABBEDDIALOG); // Disable automation menu L_AnnSetAutoMenuEnable(pData->hAutomation, FALSE); pData->fHandleSelected = FALSE; pData->fUserHandleSelected = FALSE; pData->hObjectChange = 0; pData->bMoving = FALSE; pData->ObjectWholeBodyAnalysis.bLineAdjust = FALSE; pData->ObjectWholeBodyAnalysis.ptLineAdjust[0].x = 0; pData->ObjectWholeBodyAnalysis.ptLineAdjust[0].y = 0; pData->ObjectWholeBodyAnalysis.ptLineAdjust[1].x = 0; pData->ObjectWholeBodyAnalysis.ptLineAdjust[1].y = 0; return(TRUE); } static void Child_OnPaint(HWND hwnd) { DECLARECHILDDATA(hwnd, pData); PAINTSTRUCT ps; HPALETTE hPalette; BeginPaint (hwnd, &ps); if(pData->Bitmap.Flags.Allocated) { if (pData->hPalette) hPalette = SelectPalette (ps.hdc, pData->hPalette, TRUE); GetClientRect(hwnd, &pData->rcClient); GetWindowRect(hwnd, &pData->rcWindow); L_PaintDC (ps.hdc, &pData->Bitmap, NULL, NULL, &pData->rcView, &ps.rcPaint, SRCCOPY); if (pData->hPalette) SelectPalette (ps.hdc, hPalette, TRUE); L_AnnDraw(ps.hdc, &ps.rcPaint, pData->hContainer); } EndPaint (hwnd, &ps); } static BOOL Child_OnQueryNewPalette (HWND hwnd) { DECLARECHILDDATA(hwnd, pData); HDC hDC; HPALETTE hPalette; int nNoColors = 0; if (pData->hPalette) { DeleteObject (pData->hPalette); pData->hPalette = NULL; } if (pData->Bitmap.Flags.Allocated) { hDC = GetDC (hwndFrame); pData->hPalette = L_CreatePaintPalette (hDC, &pData->Bitmap); if(pData->hPalette) { hPalette = SelectPalette (hDC, pData->hPalette, FALSE); nNoColors = RealizePalette (hDC); if (nNoColors) InvalidateRect (hwnd, NULL, FALSE); SelectPalette (hDC, hPalette, TRUE); } ReleaseDC (hwndFrame, hDC); } return(nNoColors); } static void Child_OnPaletteChanged (HWND hwnd, HWND hwndPaletteChange) { DECLARECHILDDATA(hwnd, pData); HDC hDC; HPALETTE hPalette; if (hwnd == hwndPaletteChange) return; if (pData->hPalette) { DeleteObject (pData->hPalette); pData->hPalette = NULL; } hDC = GetDC (hwnd); pData->hPalette = L_CreatePaintPalette (hDC, &pData->Bitmap); hPalette = SelectPalette (hDC, pData->hPalette, TRUE); RealizePalette (hDC); InvalidateRect (hwnd, NULL, FALSE); SelectPalette (hDC, hPalette, TRUE); ReleaseDC (hwnd, hDC); } static VOID Child_OnDestroy (HWND hwnd) { DECLARECHILDDATA(hwnd, pData); if(pData) { if(pData->hAutomation) { L_AnnSetActiveState(pData->hAutomation, ANNACTIVE_DISABLED); L_AnnDestroy(pData->hAutomation, ANNFLAG_NOINVALIDATE); } if(pData->hContainer) L_AnnDestroy(pData->hContainer, ANNFLAG_NOINVALIDATE); if (pData->hPalette) DeleteObject (pData->hPalette); if (pData->Bitmap.Flags.Allocated) L_FreeBitmap (&pData->Bitmap); GlobalFreePtr (pData); } } static void Child_MDIActivate(HWND hwnd, BOOL fActive, HWND hwndActivate, HWND hwndDeactivate) { DECLARECHILDDATA(hwnd, pData); L_UINT uTool; CheckMenuItem(GetMenu(hwnd), IDM_USERDESIGN, MF_UNCHECKED); CheckMenuItem(GetMenu(hwnd), IDM_USERRUN, MF_UNCHECKED); if(fActive) { FORWARD_WM_QUERYNEWPALETTE (hwnd, SendMessage); SetFocus(hwnd); if(hwndToolBar) L_AnnGetToolBarChecked(hwndToolBar, &uTool); L_AnnSetTool(pData->hAutomation, uTool); } return; } static int DoDialogBoxParam(int nDialog, HWND hwnd, DLGPROC pfnDialog, LPARAM lParam) { DLGPROC pfn; int nRet; pfn = (DLGPROC) MakeProcInstance((FARPROC) pfnDialog, hInst); nRet = DialogBoxParam (hInst, MAKEINTRESOURCE (nDialog), hwnd, pfn, lParam); FreeProcInstance((FARPROC) pfn); return(nRet); } static void MatchAspectRatio (LPRECT pRect, int nWidth, int nHeight) { int cxRect, cyRect; cyRect = RECTHEIGHT (pRect); cxRect = MulDiv (cyRect, nWidth, nHeight); if (cxRect > RECTWIDTH (pRect)) { cxRect = RECTWIDTH (pRect); cyRect = MulDiv (cxRect, nHeight, nWidth); } pRect->bottom = pRect->top + cyRect; pRect->right = pRect->left + cxRect; return; } void Child_ProcessSize(HWND hwnd, UINT state, int cx, int cy) { DECLARECHILDDATA(hwnd, pData); static BOOL fSizeInUse = FALSE; int nWidth, nHeight, nVScroll, nHScroll; DWORD dwStyle; L_INT cxOldClient, cyOldClient; if (!fSizeInUse) { fSizeInUse = TRUE; if (state != SIZEICONIC) { if (pData->fFitImage) { nWidth = 0; nHeight = 0; } else { nWidth = MulDiv (BITMAPWIDTH(&pData->Bitmap), pData->nZoom, 100); nHeight = MulDiv (BITMAPHEIGHT(&pData->Bitmap), pData->nZoom, 100); } cxOldClient = pData->cxClient; cyOldClient = pData->cyClient; pData->cxClient = cx; pData->cyClient = cy; dwStyle = GetWindowLong (hwnd, GWL_STYLE); nVScroll = GetSystemMetrics (SM_CXVSCROLL) - GetSystemMetrics(SM_CXBORDER); nHScroll = GetSystemMetrics (SM_CYHSCROLL) - GetSystemMetrics(SM_CYBORDER); if (WS_VSCROLL & dwStyle) pData->cxClient += nVScroll; if (WS_HSCROLL & dwStyle) pData->cyClient += nHScroll; if (pData->cxClient < nWidth) { pData->cyClient -= nHScroll; if (pData->cyClient < nHeight) pData->cxClient -= nVScroll; } else if (pData->cyClient < nHeight) { pData->cxClient -= nVScroll; if (pData->cxClient < nWidth) pData->cyClient -= nHScroll; } pData->nHScrollStep = max (1, pData->cxClient / 10); pData->nVScrollStep = max (1, pData->cyClient / 10); pData->nVScrollMax = max (0, (nHeight - pData->cyClient /*- 1*/)); pData->nVScrollPos = max (0, min (pData->nVScrollPos, pData->nVScrollMax)); pData->nHScrollMax = max (0, (nWidth - pData->cxClient /*- 1*/)); pData->nHScrollPos = max (0, min (pData->nHScrollPos, pData->nHScrollMax)); if (pData->fFitImage) { SetRect (&pData->rcView, 0, 0, pData->cxClient, pData->cyClient); MatchAspectRatio (&pData->rcView, BITMAPWIDTH(&pData->Bitmap), BITMAPHEIGHT(&pData->Bitmap)); } else { RECT rcView = pData->rcView; SetRect (&pData->rcView, 0, 0, nWidth, nHeight); OffsetRect (&pData->rcView, -pData->nHScrollPos, -pData->nVScrollPos); // check if I can avoid repainting the old window if(EqualRect(&pData->rcView, &rcView)) { RECT rc; // I don't have to redraw the old portion if the top-left corner of the window hasn't moved GetWindowRect(hwnd, &rc); if(rc.left == pData->rcWindow.left && rc.top == pData->rcWindow.top) { SetRect(&rc, 0, 0, cxOldClient, cyOldClient); IntersectRect(&rc, &rc, &pData->rcClient); ValidateRect(hwnd, &rc); } } } SetScrollRange (hwnd, SB_HORZ, 0, pData->nHScrollMax, FALSE); SetScrollPos (hwnd, SB_HORZ, pData->nHScrollPos, TRUE); SetScrollRange (hwnd, SB_VERT, 0, pData->nVScrollMax, FALSE); SetScrollPos (hwnd, SB_VERT, pData->nVScrollPos, TRUE); L_AnnSetOffsetX(pData->hContainer, (L_DOUBLE) pData->rcView.left, ANNFLAG_NOINVALIDATE); L_AnnSetOffsetY(pData->hContainer, (L_DOUBLE) pData->rcView.top, ANNFLAG_NOINVALIDATE); L_AnnSetScalarX(pData->hContainer, (L_DOUBLE) RECTWIDTH(&pData->rcView) / BITMAPWIDTH(&pData->Bitmap), ANNFLAG_NOINVALIDATE); L_AnnSetScalarY(pData->hContainer, (L_DOUBLE) RECTHEIGHT(&pData->rcView) / BITMAPHEIGHT(&pData->Bitmap), ANNFLAG_NOINVALIDATE); } fSizeInUse = FALSE; } } void Child_SizeChange(HWND hwnd, BOOL fInvalidate) { DECLARECHILDDATA(hwnd, pData); RECT rcClient; if (fInvalidate) InvalidateRect (hwnd, NULL, TRUE); GetClientRect (hwnd, &rcClient); Child_ProcessSize (hwnd, IsIconic (hwnd) ? SIZEICONIC : SIZENORMAL, RECTWIDTH (&rcClient), RECTHEIGHT (&rcClient)); } void Child_OnSize(HWND hwnd, UINT state, int cx, int cy) { DECLARECHILDDATA(hwnd, pData); Child_ProcessSize(hwnd, state, cx, cy); DefMDIChildProc (hwnd, WM_SIZE, (WPARAM) state, MAKELPARAM (cy, cx)); } BOOL CALLBACK L_EXPORT RangeDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static LPRANGEPARM pParm; int n; BOOL fTranslated; switch (msg) { case WM_INITDIALOG: pParm = (LPRANGEPARM) lParam; SetWindowText (hDlg, (LPTSTR) pParm->szTitle); SetDlgItemText (hDlg, IDC_RANGELABEL, (LPTSTR) pParm->szLabel); SetScrollRange (GetDlgItem (hDlg, IDC_RANGESCROLL), SB_CTL, pParm->nMin, pParm->nMax, FALSE); SetScrollPos (GetDlgItem (hDlg, IDC_RANGESCROLL), SB_CTL, pParm->nValue, TRUE); SetDlgItemInt (hDlg, IDC_RANGEEDIT, pParm->nValue, TRUE); return (TRUE); case WM_HSCROLL: n = GetDlgItemInt (hDlg, IDC_RANGEEDIT, &fTranslated, TRUE); if (!(!fTranslated || n < pParm->nMin || n > pParm->nMax)) pParm->nValue = n; switch (SCROLLCODE(wParam, lParam)) { case SB_LEFT: pParm->nValue = pParm->nMin; break; case SB_RIGHT: pParm->nValue = pParm->nMax; break; case SB_THUMBPOSITION: case SB_THUMBTRACK: pParm->nValue = SCROLLPOS(wParam, lParam); break; case SB_LINELEFT: pParm->nValue = max (pParm->nValue - pParm->nStep, pParm->nMin); break; case SB_LINERIGHT: pParm->nValue = min (pParm->nValue + pParm->nStep, pParm->nMax); break; case SB_PAGELEFT: pParm->nValue = max (pParm->nValue - pParm->nPage, pParm->nMin); break; case SB_PAGERIGHT: pParm->nValue = min (pParm->nValue + pParm->nPage, pParm->nMax); break; } SetDlgItemInt (hDlg, IDC_RANGEEDIT, pParm->nValue, TRUE); SetScrollPos (GetDlgItem (hDlg, IDC_RANGESCROLL), SB_CTL, pParm->nValue, TRUE); return (TRUE); case WM_COMMAND: switch (CTLID(wParam, lParam)) { case IDC_RANGEEDIT: switch (NOTIFYCODE(wParam, lParam)) { case EN_CHANGE: n = GetDlgItemInt (hDlg, IDC_RANGEEDIT, &fTranslated, TRUE); if (!(!fTranslated || n < pParm->nMin || n > pParm->nMax)) { pParm->nValue = n; SetScrollPos (GetDlgItem (hDlg, IDC_RANGESCROLL), SB_CTL, pParm->nValue, TRUE); } break; } return (TRUE); case IDOK: n = GetDlgItemInt (hDlg, IDC_RANGEEDIT, &fTranslated, TRUE); if (!fTranslated || n < pParm->nMin || n > pParm->nMax) { SetFocus (GetDlgItem (hDlg, IDC_RANGEEDIT)); SendDlgItemMessage(hDlg, IDC_RANGEEDIT, EM_SETSEL, TRUE, MAKELPARAM(0, -1)); } else { pParm->nValue = n; EndDialog (hDlg, IDOK); } return (TRUE); case IDCANCEL: EndDialog (hDlg, IDCANCEL); return (TRUE); } } return (FALSE); } static int GetZoomFactor (HWND hWnd, int nInit) { RANGEPARM Parm; lstrcpy (Parm.szTitle, TEXT("Zoom Factor")); lstrcpy (Parm.szLabel, TEXT("&Percentage")); Parm.nValue = nInit; Parm.nMin = 1; Parm.nMax = 32000; Parm.nStep = 1; Parm.nPage = 100; switch (DoDialogBoxParam (IDD_RANGE, hWnd, (DLGPROC) RangeDlgProc, (LPARAM) (LPRANGEPARM) &Parm)) { case IDOK: break; case IDCANCEL: default: Parm.nValue = -1; break; } return (Parm.nValue); } static L_VOID SetZoomFactor (HWND hwnd, int nZoom) { DECLARECHILDDATA(hwnd, pData); DWORD dwStyle; int nHScroll, nVScroll; int nHeight, nWidth; RECT rcClient; int cxClient, cyClient; int x, y; GetClientRect (hwnd, &rcClient); cxClient = RECTWIDTH (&rcClient); cyClient = RECTHEIGHT (&rcClient); x = cxClient / 2; y = cyClient / 2; nWidth = MulDiv (BITMAPWIDTH(&pData->Bitmap), nZoom, 100); nHeight = MulDiv (BITMAPHEIGHT(&pData->Bitmap), nZoom, 100); dwStyle = GetWindowLong (hwnd, GWL_STYLE); nVScroll = GetSystemMetrics (SM_CXVSCROLL) - GetSystemMetrics(SM_CXBORDER); nHScroll = GetSystemMetrics (SM_CYHSCROLL) - GetSystemMetrics(SM_CYBORDER); if (dwStyle & WS_VSCROLL) cxClient += nVScroll; if (dwStyle & WS_HSCROLL) cyClient += nHScroll; if (cxClient < nWidth) { cyClient -= nHScroll; if (cyClient < nHeight) cxClient -= nVScroll; } else if (cyClient < nHeight) { cxClient -= nVScroll; if (cxClient < nWidth) cyClient -= nHScroll; } pData->nVScrollMax = max (0, (int) nHeight - (int) cyClient /*- 1*/); pData->nHScrollMax = max (0, (int) nWidth - (int) cxClient /*- 1*/); pData->nVScrollStep = max (1, cyClient / 10); pData->nHScrollStep = max (1, cxClient / 10); if(RECTWIDTH(&pData->rcView)) pData->nHScrollPos = (int) ((long) (x - pData->rcView.left) * nWidth / RECTWIDTH(&pData->rcView)) - (cxClient / 2); if(RECTHEIGHT(&pData->rcView)) pData->nVScrollPos = (int) ((long) (y - pData->rcView.top) * nHeight / RECTHEIGHT(&pData->rcView)) - (cyClient / 2); pData->nVScrollPos = max (0, min (pData->nVScrollPos, pData->nVScrollMax)); pData->nHScrollPos = max (0, min (pData->nHScrollPos, pData->nHScrollMax)); pData->nZoom = nZoom; return; } static void Child_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { DECLARECHILDDATA(hwnd, pData); HCURSOR hCursor; HDC hDC; RECT rc; int nValue; switch(id) { case IDM_ANNENUMERATENODES: { pHANNOBJECT pAnnArray = NULL; L_UINT uCount=0; L_UINT i; L_INT nRet; CHANGEHANDLE ChangeHandle; memset(&ChangeHandle, 0, sizeof(CHANGEHANDLE)); ChangeHandle.hWnd = hwnd; ChangeHandle.bContinue = TRUE; L_AnnGetSelectCount(pData->hContainer, &uCount); pAnnArray = (pHANNOBJECT)malloc( sizeof(HANNOBJECT) * uCount); if (pAnnArray) { L_AnnGetSelectItems(pData->hContainer, pAnnArray); for (i=0; ihContainer, ANNFLAG_RECURSE | ANNFLAG_NOTCONTAINER , NULL); AnnClearAllID(pData->hContainer); } break; case IDM_SAVEAS: SaveBitmap(hwnd); break; case IDM_PRINT: hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)); hDC = L_PrintBitmap (NULL, NULL, 0, 0, 0, 0, FALSE); // do not pass 0 for rc.left or rc.top, otherwise L_PrintBitmapExt will center the bitmap // in the page and the annotations and bitmap get out of sync. SetRect(&rc, 1, 1, MulDiv(BITMAPWIDTH(&pData->Bitmap), GetDeviceCaps(hDC,LOGPIXELSX), pData->Bitmap.XResolution), MulDiv(BITMAPHEIGHT(&pData->Bitmap), GetDeviceCaps(hDC,LOGPIXELSY), pData->Bitmap.YResolution) ); // if the page is too small, fit to page if(rc.right > GetDeviceCaps (hDC, HORZRES)) { rc.bottom = MulDiv(rc.bottom, GetDeviceCaps (hDC, HORZRES), rc.right); rc.right = GetDeviceCaps (hDC, HORZRES); } if(rc.bottom > GetDeviceCaps (hDC, VERTRES)) { rc.right = MulDiv(rc.right, GetDeviceCaps (hDC, VERTRES), rc.bottom); rc.bottom = GetDeviceCaps (hDC, VERTRES); } hDC = L_PrintBitmap(hDC, &pData->Bitmap, rc.left, rc.top, RECTWIDTH(&rc), RECTHEIGHT(&rc), FALSE); L_AnnPrint(hDC, &rc, pData->hContainer); L_PrintBitmap(hDC, NULL, 0, 0, 0, 0, TRUE); SetCursor (hCursor); break; case IDM_NORMAL: pData->fFitImage = FALSE; pData->nZoom = 100; Child_SizeChange (hwnd, TRUE); break; case IDM_ZOOM: if ((nValue = GetZoomFactor (hwnd, pData->nZoom)) > 0) { pData->fFitImage = FALSE; SetZoomFactor (hwnd, nValue); Child_SizeChange (hwnd, TRUE); } break; case IDM_FITIMAGE: pData->fFitImage = TRUE; pData->nZoom = 100; Child_SizeChange(hwnd, TRUE); break; } } static void Child_OnVScroll(HWND hwnd, HWND hwndCtl, UINT code, int pos) { int nScrollInc; DECLARECHILDDATA(hwnd, pData); pData->fInScroll = TRUE; switch (code) { case SB_BOTTOM: nScrollInc = pData->nVScrollMax - pData->nVScrollPos; break; case SB_TOP: nScrollInc = -pData->nVScrollPos; break; case SB_LINEDOWN: nScrollInc = pData->nVScrollStep; break; case SB_LINEUP: nScrollInc = -pData->nVScrollStep; break; case SB_PAGEDOWN: nScrollInc = max (pData->nVScrollStep, (pData->cyClient - pData->nVScrollStep)); break; case SB_PAGEUP: nScrollInc = -max (pData->nVScrollStep, (pData->cyClient - pData->nVScrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = pos - pData->nVScrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-pData->nVScrollPos, min (nScrollInc, (pData->nVScrollMax - pData->nVScrollPos))); if(nScrollInc) { pData->nVScrollPos += nScrollInc; OffsetRect (&pData->rcView, 0, -nScrollInc); L_AnnSetOffsetY(pData->hContainer, (L_DOUBLE) pData->rcView.top, ANNFLAG_NOINVALIDATE); ScrollWindow (hwnd, 0, -nScrollInc, NULL, NULL); SetScrollPos (hwnd, SB_VERT, pData->nVScrollPos, TRUE); UpdateWindow (hwnd); } pData->fInScroll = FALSE; } static VOID Child_OnHScroll (HWND hwnd, HWND hwndCtl, UINT code, int pos) { int nScrollInc; DECLARECHILDDATA(hwnd, pData); pData->fInScroll = TRUE; switch (code) { case SB_LEFT: nScrollInc = -pData->nHScrollPos; break; case SB_RIGHT: nScrollInc = pData->nHScrollMax - pData->nHScrollPos; break; case SB_LINELEFT: nScrollInc = -pData->nHScrollStep; break; case SB_LINERIGHT: nScrollInc = pData->nHScrollStep; break; case SB_PAGELEFT: nScrollInc = -max (pData->nHScrollStep, (pData->cxClient - pData->nHScrollStep)); break; case SB_PAGERIGHT: nScrollInc = max (pData->nHScrollStep, (pData->cxClient - pData->nHScrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = pos - pData->nHScrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-pData->nHScrollPos, min (nScrollInc, (pData->nHScrollMax - pData->nHScrollPos))); if(nScrollInc) { pData->nHScrollPos += nScrollInc; OffsetRect (&pData->rcView, -nScrollInc, 0); L_AnnSetOffsetX(pData->hContainer, (L_DOUBLE) pData->rcView.left, ANNFLAG_NOINVALIDATE); ScrollWindow (hwnd, -nScrollInc, 0, NULL, NULL); SetScrollPos (hwnd, SB_HORZ, pData->nHScrollPos, TRUE); UpdateWindow (hwnd); } pData->fInScroll = FALSE; } static BOOL Child_OnEraseBkgnd (HWND hwnd, HDC hdc) { HGDIOBJ hBrush; HRGN hClientRgn, hFillRgn; RECT rcView, rcClient; DECLARECHILDDATA(hwnd, pData); if (IsIconic (hwnd)) hBrush = GetStockObject (BLACK_BRUSH); else hBrush = GETHBRBACKGROUND (hwnd); GetClientRect (hwnd, &rcClient); if (pData->fInScroll || !pData->fFitImage) { IntersectRect (&rcView, &pData->rcView, &rcClient); hClientRgn = CreateRectRgnIndirect (&rcClient); hFillRgn = CreateRectRgnIndirect (&rcView); CombineRgn (hFillRgn, hClientRgn, hFillRgn, RGN_DIFF); FillRgn (hdc, hFillRgn, hBrush); DeleteObject (hFillRgn); DeleteObject (hClientRgn); } else { FillRect (hdc, &rcClient, hBrush); } return(TRUE); } LRESULT Child_OnLtAnnEvent(HWND hwnd, int id, LPARAM lParam) { L_INT nMainID; L_INT nPartID; DECLARECHILDDATA(hwnd, pData); HANNOBJECT hObject = (HANNOBJECT)lParam; pANNHANDLE pAnnHandles = NULL; switch(id) { case LTANNEVENT_HIGHLIGHT: // Process this message for // 1. WholeBodyAnalysis annotation // This is used to customize the behavior of the highlighting action // There is no L_AnnDefine constant for moving and resizing a line // This message allows you to customize the hilighting behavior // 2. AP Spine Measure // This is used when creating the annotation throught the menu // to draw the vertical line. There is no L_AnnDefine constant for // moving and resizing a line // This message allows you to customize the hilighting behavior { pANNHILIGHT pAnnHilight = (pANNHILIGHT)lParam; hObject = pAnnHilight->hObject; AnnGetID(hObject, &nMainID, &nPartID); switch(nMainID) { case ANNTOOL_AP_SPINE_ANGULATED: case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_Hilight(pData, pAnnHilight); break; case ANNTOOL_EXAMPLE1: Example1_Hilight(pData, pAnnHilight); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_Hilight(pData, pAnnHilight); break; } } break; case LTANNEVENT_AUTOITEMCHANGED: { // Process this message only for the HipAnalysis annotation // The rotate handle moves whenever the object is moved AnnGetID(hObject, &nMainID, &nPartID); switch(nMainID) { case ANNTOOL_HIP_ANALYSIS1: HipAnalysis_Move((HANNOBJECT)lParam, 1); break; case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_Move((HANNOBJECT)lParam, 2); break; } } break; case LTANNEVENT_LBUTTONDOWN: { pANNMOUSEPOS pMousePos = (pANNMOUSEPOS)lParam; ANNHITTESTINFO HitTestInfo; L_UINT uResult; HANNOBJECT hObject; // Remove the "shift" key -- this ignores grouping pMousePos->uKeyFlags &= ~MK_SHIFT; HitTestInfo.uStructSize = sizeof(ANNHITTESTINFO); L_AnnHitTestExt(pData->hContainer, &pMousePos->pt, &uResult, &hObject, &HitTestInfo, sizeof(ANNHITTESTINFO)); if (uResult == ANNHIT_BODY) { // This happens when clicking on the body of an annotation (but not a handle) // Here we restrict the annotation to the container AnnGetID(hObject, &pData->nMainID, &pData->nPartID); pData->bMoving = TRUE; switch(pData->nMainID) { // Grouped objects case ANNTOOL_EXAMPLE1: case ANNTOOL_AP_SPINE_ANGULATED: case ANNTOOL_AP_SPINE_MEASURE: case ANNTOOL_AP_SPINE_ANALYSIS: case ANNTOOL_FOREARM_ROUGH: case ANNTOOL_WHOLE_BODY_ANALYSIS: case ANNTOOL_HIP_MEASURE_LEFT: case ANNTOOL_HIP_MEASURE_RIGHT: case ANNTOOL_AP_SPINE_ROUGH: case ANNTOOL_ANALYSIS_LATERAL_SPINE: ObjectClipCursor(pData, hObject, pMousePos->pt, OBJECT_CLIP_CURSOR_GROUP, FALSE); break; // singleton objects case ANNTOOL_BOX_SIDE: case ANNTOOL_BOX_CORNER: case ANNTOOL_BOX_EIGHT_CORNER: ObjectClipCursor(pData, hObject, pMousePos->pt, OBJECT_CLIP_CURSOR_SINGLETON, FALSE); break; // special case objects case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_ClipCursor(pData, hObject, pMousePos->pt, FALSE); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_ClipCursor(pData, hObject, pMousePos->pt, FALSE); break; } } else if (uResult == ANNHIT_USER_HANDLE) { AnnGetID(hObject, &pData->nMainID, &pData->nPartID); pData->hObjectChange = hObject; pData->fUserHandleSelected = TRUE; pData->nUserHandleID = HitTestInfo.nHandleID; pData->fLeftButtonDown = TRUE; pData->pt0 = pMousePos->pt; switch(pData->nMainID) { case ANNTOOL_EXAMPLE1: Example1_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ANGULATED: SpineAngulated_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ROUGH: SpineRough_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ANALYSIS: SpineAnalysis_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_HIP_ANALYSIS1: pData->ObjectHipAnalysis.nType = 1; HipAnalysis_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_HIP_ANALYSIS2: pData->ObjectHipAnalysis.nType = 2; HipAnalysis_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_HIP_MEASURE_RIGHT: pData->ObjectHipMeasure.nType = HIP_MEASURE_RIGHT; HipMeasure_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_HIP_MEASURE_LEFT: pData->ObjectHipMeasure.nType = HIP_MEASURE_LEFT; HipMeasure_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_ANALYSIS_LATERAL_SPINE: AnalysisLateralSpine_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_FOREARM_ROUGH: ForearmRough_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_BOX_CORNER: BoxCorner_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_BOX_EIGHT_CORNER: BoxEightCorner_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_BOX_SIDE: BoxSide_Handle_LButtonDown(pData, pMousePos); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_Handle_LButtonDown(pData, pMousePos); break; } SetCapture(hwnd); L_AnnRestrictCursor(pData->hContainer, NULL, NULL, &pData->rcOldClip, TRUE); } } break; case LTANNEVENT_MOUSEMOVE: { pANNMOUSEPOS pMousePos = (pANNMOUSEPOS)lParam; if ((pData->fUserHandleSelected) && (!pData->bMoving)) { switch(pData->nMainID) { case ANNTOOL_EXAMPLE1: Example1_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ANGULATED: SpineAngulated_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ROUGH: SpineRough_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ANALYSIS: SpineAnalysis_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_HIP_MEASURE_LEFT: case ANNTOOL_HIP_MEASURE_RIGHT: HipMeasure_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_ANALYSIS_LATERAL_SPINE: AnalysisLateralSpine_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_FOREARM_ROUGH: ForearmRough_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_BOX_CORNER: BoxCorner_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_BOX_EIGHT_CORNER: BoxEightCorner_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_BOX_SIDE: BoxSide_Handle_MouseMove(pData, pMousePos); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_Handle_MouseMove(pData, pMousePos); break; } } } break; case LTANNEVENT_LBUTTONUP: { pANNMOUSEPOS pMousePos = (pANNMOUSEPOS)lParam; if (pData->bMoving) { switch(pData->nMainID) { case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_AnnSetLineHeight(pData->ObjectHipAnalysis.hLineRotate, pData->hContainer, pData->ObjectHipAnalysis.nType); break; } } else if (pData->fUserHandleSelected) { switch(pData->nMainID) { case ANNTOOL_EXAMPLE1: Example1_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ANGULATED: SpineAngulated_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ROUGH: SpineRough_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_AP_SPINE_ANALYSIS: SpineAnalysis_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_HIP_MEASURE_LEFT: case ANNTOOL_HIP_MEASURE_RIGHT: HipMeasure_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_ANALYSIS_LATERAL_SPINE: AnalysisLateralSpine_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_FOREARM_ROUGH: ForearmRough_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_BOX_CORNER: BoxCorner_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_BOX_EIGHT_CORNER: BoxEightCorner_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_BOX_SIDE: BoxSide_Handle_LButtonUp(pData, pMousePos); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_Handle_LButtonUp(pData, pMousePos); break; } pData->hObjectChange = 0; ReleaseCapture(); } DebugClipCursor(NULL); pData->fUserHandleSelected = FALSE; pData->fHandleSelected = FALSE; pData->fLeftButtonDown = FALSE; pData->hObjectChange = 0; pData->bMoving = FALSE; } break; } return(0); } void Child_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) { L_UINT uTool; DECLARECHILDDATA(hwnd, pData); L_AnnGetToolBarChecked(hwndToolBar, &uTool); pData->ptStart.x = x; pData->ptStart.y = y; switch(uTool) { case ANNTOOL_EXAMPLE1: Example1_LButtonDown(hwnd, pData); break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_LButtonDown(hwnd, pData); break; case ANNTOOL_AP_SPINE_ROUGH: SpineRough_LButtonDown(hwnd, pData); break; case ANNTOOL_AP_SPINE_ANGULATED: SpineAngulated_LButtonDown(hwnd, pData); break; case ANNTOOL_AP_SPINE_ANALYSIS: SpineAnalysis_LButtonDown(hwnd, pData); break; case ANNTOOL_HIP_ANALYSIS1: pData->ObjectHipAnalysis.nType = 1; HipAnalysis_LButtonDown(hwnd, pData); break; case ANNTOOL_HIP_ANALYSIS2: pData->ObjectHipAnalysis.nType = 2; HipAnalysis_LButtonDown(hwnd, pData); break; case ANNTOOL_HIP_MEASURE_LEFT: pData->ObjectHipMeasure.nType = HIP_MEASURE_LEFT; HipMeasure_LButtonDown(hwnd, pData); break; case ANNTOOL_HIP_MEASURE_RIGHT: pData->ObjectHipMeasure.nType = HIP_MEASURE_RIGHT; HipMeasure_LButtonDown(hwnd, pData); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_LButtonDown(hwnd, pData); break; case ANNTOOL_ANALYSIS_LATERAL_SPINE: AnalysisLateralSpine_LButtonDown(hwnd, pData); break; case ANNTOOL_FOREARM_ROUGH: ForearmRough_LButtonDown(hwnd, pData); break; case ANNTOOL_BOX_CORNER: BoxCorner_LButtonDown(hwnd, pData); break; case ANNTOOL_BOX_EIGHT_CORNER: BoxEightCorner_LButtonDown(hwnd, pData); break; case ANNTOOL_BOX_SIDE: BoxSide_LButtonDown(hwnd, pData); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_LButtonDown(hwnd, pData); break; } } void Child_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags) { L_UINT uTool; DECLARECHILDDATA(hwnd, pData); L_AnnGetToolBarChecked(hwndToolBar, &uTool); if(pData->fCapture) { pData->ptMove.x = x; pData->ptMove.y = y; switch(uTool) { case ANNTOOL_EXAMPLE1: Example1_MouseMove(pData); break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_MouseMove(pData); break; case ANNTOOL_AP_SPINE_ROUGH: L_AnnDefine(pData->hRect, &pData->ptMove, ANNDEFINE_APPEND); break; case ANNTOOL_AP_SPINE_ANGULATED: L_AnnDefine(pData->hRect, &pData->ptMove, ANNDEFINE_APPEND); break; case ANNTOOL_AP_SPINE_ANALYSIS: L_AnnDefine(pData->hRect, &pData->ptMove, ANNDEFINE_APPEND); break; case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_MouseMove(pData); break; case ANNTOOL_HIP_MEASURE_LEFT: case ANNTOOL_HIP_MEASURE_RIGHT: HipMeasure_MouseMove(pData); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_MouseMove(pData); break; case ANNTOOL_ANALYSIS_LATERAL_SPINE: L_AnnDefine(pData->hRect, &pData->ptMove, ANNDEFINE_APPEND); break; case ANNTOOL_FOREARM_ROUGH: ForearmRough_MouseMove(pData); break; case ANNTOOL_BOX_CORNER: BoxCorner_MouseMove(pData); break; case ANNTOOL_BOX_EIGHT_CORNER: BoxEightCorner_MouseMove(pData); break; case ANNTOOL_BOX_SIDE: BoxSide_MouseMove(pData); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_MouseMove(pData); break; default: L_AnnDefine(pData->hRect, &pData->ptMove, ANNDEFINE_APPEND); break; } } } #define MIN_DELTA (20) #define CHECK_OK (0x001) #define CHECK_WIDTH_TOO_SMALL (0x002) #define CHECK_HEIGHT_TOO_SMALL (0x004) #define CHECK_BOTH_TOO_SMALL (0x006) unsigned int CheckStartEndPoints(LPPOINT pptStart, LPPOINT pptEnd) { unsigned int uRet = 0; if (abs(pptStart->x - pptEnd->x) < MIN_DELTA) uRet |= CHECK_WIDTH_TOO_SMALL; if (abs(pptStart->y - pptEnd->y) < MIN_DELTA) uRet |= CHECK_HEIGHT_TOO_SMALL; return uRet; } void Child_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags) { L_TCHAR *pszMsg; L_UINT uFlags; L_UINT uTool; DECLARECHILDDATA(hwnd, pData); L_AnnGetToolBarChecked(hwndToolBar, &uTool); if(pData->fCapture) { pData->ptEnd.x = x; pData->ptEnd.y = y; uFlags = CheckStartEndPoints(&pData->ptStart, &pData->ptEnd); pData->fCapture = FALSE; L_AnnSetSelected(pData->hContainer, FALSE, ANNFLAG_RECURSE); switch(uTool) { case ANNTOOL_EXAMPLE1: Example1_LButtonUp(pData, uTool); break; case ANNTOOL_AP_SPINE_MEASURE: SpineMeasure_LButtonUp(pData, uTool); break; case ANNTOOL_AP_SPINE_ROUGH: SpineRough_LButtonUp(pData, uTool); break; case ANNTOOL_AP_SPINE_ANGULATED: SpineAngulated_LButtonUp(pData, uTool); break; case ANNTOOL_AP_SPINE_ANALYSIS: SpineAnalysis_LButtonUp(pData, uTool); break; case ANNTOOL_HIP_ANALYSIS1: case ANNTOOL_HIP_ANALYSIS2: HipAnalysis_LButtonUp(pData, uTool); break; case ANNTOOL_HIP_MEASURE_LEFT: case ANNTOOL_HIP_MEASURE_RIGHT: HipMeasure_LButtonUp(pData, uTool); break; case ANNTOOL_ROUGH_LATERAL_SPINE: RoughLateralSpine_LButtonUp(pData, uTool); break; case ANNTOOL_ANALYSIS_LATERAL_SPINE: AnalysisLateralSpine_LButtonUp(pData, uTool); break; case ANNTOOL_FOREARM_ROUGH: ForearmRough_LButtonUp(pData, uTool); break; case ANNTOOL_BOX_CORNER: BoxCorner_LButtonUp(pData, uTool); break; case ANNTOOL_BOX_EIGHT_CORNER: BoxEightCorner_LButtonUp(pData, uTool); break; case ANNTOOL_BOX_SIDE: BoxSide_LButtonUp(pData, uTool); break; case ANNTOOL_WHOLE_BODY_ANALYSIS: WholeBodyAnalysis_LButtonUp(pData, uTool); break; } ClipCursor(NULL); // set the toolbar tool to be ANNTOOL_SELECT to mimic what the other tools do L_AnnSetToolBarChecked(hwndToolBar, ANNTOOL_SELECT); pszMsg = NULL; if ((uTool == ANNTOOL_ROUGH_LATERAL_SPINE) && (uFlags & CHECK_HEIGHT_TOO_SMALL)) pszMsg = TEXT("Drag a Larger Vertical Distance to Create the Object"); else if ((uTool != ANNTOOL_ROUGH_LATERAL_SPINE) && (uFlags) ) pszMsg = TEXT("Drag a Larger Rectangular Area to Create the Object"); if (pszMsg) { L_AnnDestroy(pData->hContainer, ANNFLAG_SELECTED | ANNFLAG_NOTTHIS | ANNFLAG_RECURSE); MessageBox(hwnd, pszMsg, TEXT("Warning"), MB_OK | MB_ICONEXCLAMATION); } } } LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { HANDLE_MSG (hwnd, WM_CREATE, Child_OnCreate); HANDLE_MSG (hwnd, WM_PALETTECHANGED, Child_OnPaletteChanged); HANDLE_MSG (hwnd, WM_QUERYNEWPALETTE, Child_OnQueryNewPalette); HANDLE_MSG (hwnd, WM_DESTROY, Child_OnDestroy); HANDLE_MSG (hwnd, WM_MDIACTIVATE, Child_MDIActivate); HANDLE_MSG (hwnd, WM_COMMAND, Child_OnCommand); HANDLE_MSG (hwnd, WM_PAINT, Child_OnPaint); HANDLE_MSG (hwnd, WM_SIZE, Child_OnSize); HANDLE_MSG (hwnd, WM_HSCROLL, Child_OnHScroll); HANDLE_MSG (hwnd, WM_VSCROLL, Child_OnVScroll); HANDLE_MSG (hwnd, WM_ERASEBKGND, Child_OnEraseBkgnd); HANDLE_MSG (hwnd, WM_LTANNEVENT, Child_OnLtAnnEvent); HANDLE_MSG (hwnd, WM_LBUTTONDOWN, Child_OnLButtonDown); HANDLE_MSG (hwnd, WM_MOUSEMOVE, Child_OnMouseMove); HANDLE_MSG (hwnd, WM_LBUTTONUP, Child_OnLButtonUp); } return(DefMDIChildProc (hwnd, msg, wParam, lParam)); } /* This function will get the save options filled by the Save dialog into a SAVEFILEOPTION structure to be used by the Save functions */ static SAVEDLGPARAMS FSParm; static OPENFILENAME SaveFileName; L_VOID SetSaveOptions (pSAVEFILEOPTION pSaveFileOption, LPSAVEDLGPARAMS pFSParm) { L_GetDefaultSaveFileOption(pSaveFileOption, sizeof(SAVEFILEOPTION)); pSaveFileOption->PageNumber = pFSParm->nPageNumber; pSaveFileOption->Flags = 0; switch(pFSParm->uSaveMulti) { case MULTIPAGE_OPERATION_REPLACE: pSaveFileOption->Flags|=ESO_REPLACEPAGE; break; case MULTIPAGE_OPERATION_INSERT: pSaveFileOption->Flags|=ESO_INSERTPAGE; break; case MULTIPAGE_OPERATION_APPEND: pSaveFileOption->PageNumber = 2; break; case MULTIPAGE_OPERATION_OVERWRITE: pSaveFileOption->PageNumber = 1; break; } pSaveFileOption->Passes = pFSParm->nPasses; if(pFSParm->nFormat == FILE_GIF) { if (!pFSParm->bSaveInterlaced) pSaveFileOption->Flags &= ~ESO_INTERLACED; else pSaveFileOption->Flags |= ESO_INTERLACED; } if(pFSParm->bSaveWithStamp) { pSaveFileOption->Flags |= ESO_SAVEWITHSTAMP; pSaveFileOption->StampWidth = pFSParm->nStampWidth; pSaveFileOption->StampHeight = pFSParm->nStampHeight; pSaveFileOption->StampBits = pFSParm->nStampBits; } } static void SaveBitmap(HWND hwnd) { DECLARECHILDDATA(hwnd, pData); HCURSOR hCursor; L_TCHAR szFile[_MAX_PATH]=TEXT(""); L_INT nRet; _fmemset(&SaveFileName, 0, sizeof(OPENFILENAME)); _fmemset(&FSParm, 0, sizeof(SAVEDLGPARAMS)); FSParm.uStructSize = sizeof (SAVEDLGPARAMS); if(!SaveFileName.lStructSize) { SaveFileName.nFilterIndex = 86; /* TIF 1-bit */ SaveFileName.lStructSize = sizeof(OPENFILENAME); SaveFileName.lpstrInitialDir = szImageDir; SaveFileName.lpstrTitle = TEXT("Save As"); SaveFileName.lpstrFile = szFile; SaveFileName.nMaxFile = sizeof(szFile); SaveFileName.lpstrFileTitle = FSParm.szFileName; SaveFileName.nMaxFileTitle = sizeof(FSParm.szFileName)/sizeof(L_TCHAR); SaveFileName.nFileOffset = 0; SaveFileName.Flags = 0; FSParm.nQFactor = 2; } nRet = L_DlgSave ( hwnd, &SaveFileName, &FSParm ); if(nRet == SUCCESS_DLG_OK) { hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)); SetSaveOptions(&SaveFileOption, &FSParm); lstrcpy (szFile, FSParm.szFileName); GetAnnFile(szAnnFile, szFile, 1, FSParm.nFormat); if(!lstrcmp(szAnnFile, szFile)) /* same file, save as Wang annotation */ { nRet = L_AnnSaveTag(pData->hContainer, ANNFMT_TIFFTAG, FALSE); if(nRet != SUCCESS) { if(MessageBox(hwnd, TEXT("Error creating annotation data.\n") TEXT("The file will be saved without annotations.\n\n") TEXT("Do you still want to continue?"), TEXT("Annotation Error"), MB_ICONSTOP | MB_YESNO) != IDYES) return; } } nRet = L_SaveBitmap( szFile, &pData->Bitmap, FSParm.nFormat, FSParm.nBitsPerPixel, FSParm.nQFactor, &SaveFileOption); if(nRet == SUCCESS) { if(lstrcmp(szAnnFile, szFile)) /* different file, save as Lead annotation */ nRet = L_AnnSave (szAnnFile, pData->hContainer, ANNFMT_NATIVE, FALSE, NULL); } SetCursor (hCursor); } } /*====(SetPageNumber)====================================================== Description: Sets the page number for multipage file access. Syntax : L_VOID SetPageNumber(L_INT nPage) Prototype : annotate.h Parameters : nPage Page number to be set. Return Value: None. ==========================================================================*/ L_VOID SetPageNumber(L_INT nPageNumber) { LoadFileOption.Flags = ELO_ROTATED; /* load image with rotated View Perspective */ LoadFileOption.PageNumber = nPageNumber; return; } /*====(AboutDlgProc)====================================================== Description: Processes messages for the about dialog box. Syntax : L_BOOL CALLBACK L_EXPORT AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) Prototype : annotate.h Parameters : hWnd Handle to the window using the popup menu. hMenu Handle to the menu to be used. nItem Number of items in the menu. fSystemMenu Truth of "Is the menu a system menu". Return Value: TRUE WM_INITDIALOG and WM_COMMAND (IDOK or IDCANCEL) messages processed. FALSE A different message was processed. ==========================================================================*/ #define IDS_STRING_ABOUT TEXT("") \ TEXT("The custom annotations are made from one or more 'grouped' annotation objects. ") \ TEXT("Each grouped annotation object has default handles, which are initially hidden. ") \ TEXT("The visible handles are 'user-defined' handles.\r\n\r\n") \ TEXT("Use 'Enumerate Nodes' menu option to change the properties of both default and user-defined handles.\r\n\r\n") \ TEXT("Use the 'Break All Groups' menu option to see how the objects are grouped together ") \ TEXT("to build the custom annotation. ") L_BOOL CALLBACK L_EXPORT AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, IDS_STRING_ABOUT); return(TRUE); case WM_COMMAND: switch (CTLID(wParam, lParam)) { case IDOK: case IDCANCEL: EndDialog (hDlg, 0); return(TRUE); } } return(FALSE); } /*---[ExtractCommandData]---------------------------------------------------- Syntax: L_BOOL ExtractCommandData( ); Parameters: None. ProtoType: Annotate.c Notes: - This procedure is responsible for extracting the images path passed through the command line. - You should call this function only in WinMain function. --------------------------------------------------------------------------*/ L_BOOL ExtractCommandData ( ) { LPTSTR pszFirst = NULL; LPTSTR pszCmdLine = NULL; LPTSTR psz = NULL; L_INT nFirstPos = 0 ; L_INT nStringLen = 0 ; pszCmdLine = GetCommandLine(); nStringLen = lstrlen ( pszCmdLine ) + 1 ; // To specify that it is command line or not. if(( pszCmdLine[1] == ':' ) || // Shortcut case ( pszCmdLine[2] == ':' )) //VS case { // 1- TRY TO EXPOSE THE EXE NAME FROM THE COMMAND LINE psz = _tcschr ( pszCmdLine, ':' ) ; if ( NULL == psz ) { return FALSE ; } } else { psz = pszCmdLine ; } pszFirst = _tcschr ( psz + 1, ':' ) ; if ( NULL == pszFirst ) { return FALSE ; } // Calc the char number to the image file name. nFirstPos = pszFirst - pszCmdLine - 1 ; if ( 0 > nFirstPos ) { return FALSE ; } lstrcpyn ( szImageDir, pszFirst - 1, ( nStringLen - nFirstPos ) ) ; ZeroMemory(szImageDir, sizeof(szImageDir)); fullpath(szImageDir, psz, sizeof(szImageDir)); return TRUE; }