/*[]=====================================================================[]*/ /*[] LEADTOOLS for Windows - Version 11 []*/ /*[] []*/ /*[] []*/ /*[] Copyright (c) 1991-2000 LEAD Technologies, Inc. []*/ /*[] All Rights Reserved. []*/ /*[]=====================================================================[]*/ #include /* required for all Windows applications */ #include #include "TCHAR.h" #include #include #include #include #ifndef WIN32 #include #include #define BST_CHECKED 1 #endif #include "..\\..\\..\\include\\l_bitmap.h" /* LEADTOOLS main header file */ #include "..\\..\\..\\include\\l_error.h" /* LEADTOOLS error definition header file */ #include "annotate.h" L_TCHAR szAudioFileFilter[] = { TEXT("Wave Files (*.wav)\0") TEXT("*.wav\0") TEXT("All Files (*.*)\0") TEXT("*.*\0") }; L_TCHAR szImageDir[L_MAXPATH]; #define RECTWIDTH(lpRect) (((LPRECT) lpRect)->right - ((LPRECT) lpRect)->left) #define RECTHEIGHT(lpRect) (((LPRECT) lpRect)->bottom - ((LPRECT) lpRect)->top) typedef struct _CHILDDATA { int cxClient; /* width of client area */ int cyClient; /* height of client area */ int nHScrollPos; /* x scroll position */ int nVScrollPos; /* y scroll position */ int nHScrollMax; /* maximum x scroll position */ int nVScrollMax; /* maximum y scroll postion */ int nHScrollStep; /* x scroll step value */ int nVScrollStep; /* y scroll step value */ BOOL bThumbTrack; BOOL fFitImage; int nZoom; RECT rcView; RECT rcClient; RECT rcWindow; BITMAPHANDLE Bitmap; HPALETTE hPalette; HANNOBJECT hContainer; HANNOBJECT hAutomation; BOOL fInScroll; BOOL fShowLock; HANNOBJECT hRect; HANNOBJECT hEllipse; BOOL fCapture; BOOL fLeftButtonDown; POINT pt0; BOOL bMagGlass; L_INT nMagWidth; L_INT nMagHeight; L_INT nMagZoom; L_BOOL bDoubleBuffer; L_HANDLE hDoubleBuffer; } CHILDDATA, FAR *LPCHILDDATA; #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) #define MAX_ZOOM_FACTOR 30000 #define MIN_ZOOM_FACTOR 5 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; typedef struct _HYPERLINKPARM { L_UINT uType; L_UINT uMsg; WPARAM wParam; L_TCHAR Buffer[2048]; /* buffer big enough to hold web page or application name */ } HYPERLINKPARM, FAR* LPHYPERLINKPARM; #ifdef WIN32 #define HWNDCTL(w, l) ((HWND) (l)) #define NOTIFYCODE(w, l) HIWORD(w) #define CTLID(w, l) LOWORD(w) #define SCROLLPOS(w, l) ((short) HIWORD(w)) #define SCROLLCODE(w, l) LOWORD(w) #define GETHBRBACKGROUND(hwnd) ((HBRUSH) GetClassLong(hwnd, GCL_HBRBACKGROUND)) #else #define HWNDCTL(w, l) ((HWND) HIWORD(l)) #define NOTIFYCODE(w, l) HIWORD(l) #define CTLID(w, l) (w) #define SCROLLPOS(w, l) ((short) LOWORD(l)) #define SCROLLCODE(w, l) (w) #define GETHBRBACKGROUND(hwnd) ((HBRUSH) GetClassWord(hwnd, GCW_HBRBACKGROUND)) #endif HINSTANCE hInst; HWND hwndClient; HWND hwndFrame; HWND hwndToolBar; int nAnnObject = IDM_TOOLSELECT; int nAnnUserMode = IDM_USERDESIGN; L_TCHAR szText[256]; L_TCHAR szBitmapFile[L_MAXPATH]=TEXT(""); L_TCHAR szStampFile[L_MAXPATH]=TEXT(""); L_TCHAR szAudioFile[L_MAXPATH]=TEXT(""); L_TCHAR szSaveFile[L_MAXPATH]=TEXT(""); L_TCHAR szAnnFile[L_MAXPATH]=TEXT(""); L_UINT32 uNextTag = 0; L_BOOL gbShowLockedIcon = TRUE; L_BOOL gbWangMode = FALSE; L_BOOL gbAnnHiliteCustom = FALSE; HCURSOR hCursorDefaultAnnDrawNew = NULL; HCURSOR hCursorDefaultAnnHandle = NULL; HCURSOR hCursorDefaultAnnMove = NULL; HCURSOR hCursorDefaultAnnSelect = NULL; HCURSOR hCursorAnnDrawNew = NULL; HCURSOR hCursorAnnHandle = NULL; HCURSOR hCursorAnnMove = NULL; HCURSOR hCursorAnnSelect = NULL; 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) #ifdef UNICODE //define for Unicode #define fullpath _wfullpath #else #define fullpath _fullpath #endif void CopyAnnCursors(HINSTANCE hInst) { L_AnnGetAutoCursor(NULL, ANNAUTOCURSOR_DRAWNEW, &hCursorDefaultAnnDrawNew); L_AnnGetAutoCursor(NULL, ANNAUTOCURSOR_HANDLE, &hCursorDefaultAnnHandle); L_AnnGetAutoCursor(NULL, ANNAUTOCURSOR_MOVE, &hCursorDefaultAnnMove); L_AnnGetAutoCursor(NULL, ANNAUTOCURSOR_SELECT, &hCursorDefaultAnnSelect); hCursorAnnDrawNew = LoadCursor(hInst,MAKEINTRESOURCE(IDC_ANNCROSS)); hCursorAnnHandle = LoadCursor(hInst,MAKEINTRESOURCE(IDC_ANNHANDLE)); hCursorAnnMove = LoadCursor(hInst,MAKEINTRESOURCE(IDC_ANNMOVE)); hCursorAnnSelect = LoadCursor(hInst,MAKEINTRESOURCE(IDC_ANNSELECT)); } void FreeAnnCursors() { DeleteObject(hCursorDefaultAnnDrawNew); DeleteObject(hCursorDefaultAnnHandle); DeleteObject(hCursorDefaultAnnMove); DeleteObject(hCursorDefaultAnnSelect); DeleteObject(hCursorAnnDrawNew); DeleteObject(hCursorAnnHandle); DeleteObject(hCursorAnnMove); DeleteObject(hCursorAnnSelect); } int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; L_INT nRet; static L_TCHAR szTemp[L_MAXPATH]; static L_TCHAR szCommandTemp[L_MAXPATH]; UNLOCKSUPPORT(); L_SetDisplayMode(DISPLAYMODE_SCALETOGRAY,DISPLAYMODE_SCALETOGRAY ); L_AnnSetOptions(NULL, OPTIONS_NEW_ALL); CopyAnnCursors(hInstance); ExtractCommandData ( ); nRet = L_DlgInit (DLG_INIT_COLOR); 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) && !TranslateAccelerator (hwndFrame, hAccel, &msg)) */ 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)); hwndFrame = CreateWindow (SZ_FRAMECLASS, TEXT("LEADTOOLS Annotation Example"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 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); } static L_INT MenuToTool(UINT uMenu) { switch(uMenu) { case IDM_TOOLSELECT: return ANNTOOL_SELECT; case IDM_TOOLLINE: return ANNTOOL_LINE; case IDM_TOOLRECT: return ANNTOOL_RECT; case IDM_TOOLELLIPSE: return ANNTOOL_ELLIPSE; case IDM_TOOLPOLYLINE: return ANNTOOL_POLYLINE; case IDM_TOOLPOLYGON: return ANNTOOL_POLYGON; case IDM_TOOLPOINTER: return ANNTOOL_POINTER; case IDM_TOOLFREEHAND: return ANNTOOL_FREEHAND; case IDM_TOOLHILITE: return ANNTOOL_HILITE; case IDM_TOOLPUSHPIN: return ANNTOOL_PUSHPIN; case IDM_TOOLREDACT: return ANNTOOL_REDACT; case IDM_TOOLTEXT: return ANNTOOL_TEXT; case IDM_TOOLRTF: return ANNTOOL_RTF; case IDM_TOOLNOTE: return ANNTOOL_NOTE; case IDM_TOOLSTAMP: return ANNTOOL_STAMP; case IDM_TOOLBUTTON: return ANNTOOL_BUTTON; case IDM_TOOLHOTSPOT: return ANNTOOL_HOTSPOT; case IDM_TOOLAUDIO: return ANNTOOL_AUDIO; case IDM_TOOLRULER: return ANNTOOL_RULER; case IDM_TOOLCROSSPRODUCT: return ANNTOOL_CROSSPRODUCT; case IDM_TOOLPOINT: return ANNTOOL_POINT; case IDM_TOOLPROTRACTOR: return ANNTOOL_PROTRACTOR; case IDM_TOOLFREEHANDHOTSPOT: return ANNTOOL_FREEHANDHOTSPOT; case IDM_TOOLCURVE: return ANNTOOL_CURVE; case IDM_TOOLCLOSEDCURVE: return ANNTOOL_CURVECLOSED; case IDM_TOOLENCRYPT: return ANNTOOL_ENCRYPT; case IDM_TOOLPOLYRULER: return ANNTOOL_POLYRULER; case IDM_TOOLVIDEO: return ANNTOOL_VIDEO; case IDM_TOOLTEXTPOINTER: return ANNTOOL_TEXTPOINTER; // case IDM_TOOLUSER: // return ANNTOOL_USER; default: if(uMenu >= IDM_SUBTOOL_FIRST && uMenu <= IDM_SUBTOOL_LAST) return ANNTOOL_STAMP_FIRST + uMenu - IDM_SUBTOOL_FIRST; else // unknown tool return ANNTOOL_SELECT; } } static void ToolChecked(HWND hwnd, UINT uTool) { HWND hwndChild; CheckMenuItem(GetMenu(hwnd), nAnnObject, MF_UNCHECKED); switch(uTool) { case ANNTOOL_SELECT: nAnnObject = IDM_TOOLSELECT; break; case ANNTOOL_LINE: nAnnObject = IDM_TOOLLINE; break; case ANNTOOL_RECT: nAnnObject = IDM_TOOLRECT; break; case ANNTOOL_ELLIPSE: nAnnObject = IDM_TOOLELLIPSE; break; case ANNTOOL_POLYLINE: nAnnObject = IDM_TOOLPOLYLINE; break; case ANNTOOL_POLYGON: nAnnObject = IDM_TOOLPOLYGON; break; case ANNTOOL_POINTER: nAnnObject = IDM_TOOLPOINTER; break; case ANNTOOL_FREEHAND: nAnnObject = IDM_TOOLFREEHAND; break; case ANNTOOL_HILITE: nAnnObject = IDM_TOOLHILITE; break; case ANNTOOL_PUSHPIN: nAnnObject = IDM_TOOLPUSHPIN; break; case ANNTOOL_REDACT: nAnnObject = IDM_TOOLREDACT; break; case ANNTOOL_TEXT: nAnnObject = IDM_TOOLTEXT; break; case ANNTOOL_RTF: nAnnObject = IDM_TOOLRTF; break; case ANNTOOL_NOTE: nAnnObject = IDM_TOOLNOTE; break; case ANNTOOL_STAMP: nAnnObject = IDM_TOOLSTAMP; break; case ANNTOOL_BUTTON: nAnnObject = IDM_TOOLBUTTON; break; case ANNTOOL_HOTSPOT: nAnnObject = IDM_TOOLHOTSPOT; break; case ANNTOOL_AUDIO: nAnnObject = IDM_TOOLAUDIO; break; case ANNTOOL_RULER: nAnnObject = IDM_TOOLRULER; break; case ANNTOOL_CROSSPRODUCT: nAnnObject = IDM_TOOLCROSSPRODUCT; break; case ANNTOOL_POINT: nAnnObject = IDM_TOOLPOINT; break; case ANNTOOL_PROTRACTOR: nAnnObject = IDM_TOOLPROTRACTOR; break; case ANNTOOL_FREEHANDHOTSPOT: nAnnObject = IDM_TOOLFREEHANDHOTSPOT; break; case ANNTOOL_CURVE: nAnnObject = IDM_TOOLCURVE; break; case ANNTOOL_CURVECLOSED: nAnnObject = IDM_TOOLCLOSEDCURVE; break; case ANNTOOL_ENCRYPT: nAnnObject = IDM_TOOLENCRYPT; break; // case ANNTOOL_USER: // nAnnObject = IDM_TOOLUSER; // break; default: if(uTool >= ANNTOOL_STAMP_FIRST && uTool <= ANNTOOL_STAMP_LAST) nAnnObject = IDM_SUBTOOL_FIRST + uTool - ANNTOOL_STAMP_FIRST; break; } CheckMenuItem(GetMenu(hwnd), nAnnObject, MF_CHECKED); hwndChild = FORWARD_WM_MDIGETACTIVE(hwndClient, SendMessage); if(IsWindow(hwndChild)) { DECLARECHILDDATA(hwndChild, pData); L_AnnSetTool(pData->hAutomation, uTool); } } static void MenuToolChecked(HWND hwnd, L_UINT uMenu) { CheckMenuItem(GetMenu(hwnd), nAnnObject, MF_UNCHECKED); nAnnObject = uMenu; CheckMenuItem(GetMenu(hwnd), nAnnObject, MF_CHECKED); L_AnnSetToolBarChecked(hwndToolBar, MenuToTool(uMenu)); } #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 = _tcsrchr(pDest, '.'); if(!p) p = _tcsrchr(pDest, '\0'); lstrcpy(p, TEXT(".ann")); } LoadFileOption.PageNumber = nOldPage; } /*--------------------------------------------------------------------------+ | 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; } } static OPENFILENAME OpenFileName; static OPENDLGPARAMS FOParm; BOOL GetFileName(HWND hwnd, LPTSTR pszTitle, LPTSTR pszFilter, LPTSTR pszFile) { L_INT nRet; L_TCHAR szFile[L_MAXPATH]=TEXT(""); _fmemset(&FOParm, 0, sizeof(OPENDLGPARAMS)); _fmemset(&OpenFileName, 0, sizeof(OPENFILENAME)); FOParm.uStructSize = sizeof(OPENDLGPARAMS); FOParm.bShowLoadOptions = FALSE; FOParm.bPreviewEnabled = TRUE; FOParm.uDlgFlags = DLG_OPEN_SHOW_MULTIPAGE | DLG_OPEN_SHOW_LOADROTATED | DLG_OPEN_SHOW_LOADCOMPRESSED | DLG_OPEN_SHOW_PREVIEW | DLG_OPEN_SHOW_FILEINFO; { OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.lpstrFilter = pszFilter; OpenFileName.lpstrCustomFilter = NULL; OpenFileName.nMaxCustFilter = 0; OpenFileName.nFilterIndex = 0; OpenFileName.lpstrFile = szFile; OpenFileName.nMaxFile = sizeof(szFile)/sizeof(L_TCHAR); 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_UCHAR 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_UCHAR 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 HWND MyCreateToolBar(HWND hwnd) { L_UINT uButtons; pANNBUTTON pButtons; BITMAPHANDLE UserToolBitmap; // create a toolbar identical to the default toolbar, except that it adds a user defined button // 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, 0, &uButtons) == SUCCESS) { pButtons = (pANNBUTTON)GlobalAllocPtr(GMEM_MOVEABLE, (uButtons+1) * sizeof(ANNBUTTON)); if(pButtons && L_AnnGetToolBarButtons(hwnd, pButtons, sizeof(ANNBUTTON), &uButtons) == SUCCESS) { if(LoadAsBitmap(hInst, MAKEINTRESOURCE(IDB_USERBTN), &UserToolBitmap)) { pButtons[uButtons].uFlags = 0; // I will pass the string and there is only one tool pButtons[uButtons].uTool = ANNTOOL_USER; // make sure the bitmap is TOOLBARIMAGECX x TOOLBARIMAGECY L_SizeBitmap(&UserToolBitmap, TOOLBARIMAGECX, TOOLBARIMAGECY, 0); pButtons[uButtons].pBitmapUp = pButtons[uButtons].pBitmapDown = &UserToolBitmap; #ifdef WIN32 pButtons[uButtons].nToolTipTextID = -1; pButtons[uButtons].pToolTipText = TEXT("User defined Tool"); #endif L_AnnSetToolBarButtons(hwnd, pButtons, uButtons+1); L_FreeBitmap(&UserToolBitmap); } // 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 if(pButtons) GlobalFreePtr(pButtons); } // show the toolbar ShowWindow(hwnd, SW_SHOW); return hwnd; } static UpdateMenuNewOptions(HWND hwnd) { L_UINT uOptions = 0; HMENU hMenu = GetMenu(hwnd); L_AnnGetOptions(&uOptions); CheckMenuItem(hMenu, IDM_ANNOTATIONTOOLBAR, MF_CHECKED); CheckMenuItem(hMenu, IDM_NEW_TOOLBAR, (uOptions & OPTIONS_NEW_TOOLBAR) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_METAFILES, (uOptions & OPTIONS_NEW_STAMP_METAFILES) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_ALPHA, (uOptions & OPTIONS_NEW_ALPHA) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_ROTATE, (uOptions & OPTIONS_NEW_ROTATE) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_SIDE_HANDLES, (uOptions & OPTIONS_NEW_SIDE_HANDLES) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_MULTI_SELECT, (uOptions & OPTIONS_NEW_MULTI_SELECT) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_CURSORS, (uOptions & OPTIONS_NEW_CURSORS) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_ESC_CANCEL, (uOptions & OPTIONS_NEW_ESC_CANCEL) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_CALIBRATE_RULER, (uOptions & OPTIONS_NEW_CALIBRATE_RULER) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_DOT_DASH_LINES, (uOptions & OPTIONS_NEW_DOT_DASH_LINES) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, IDM_NEW_TEXT_OPTIONS, (uOptions & OPTIONS_NEW_TEXT_OPTIONS) ? MF_CHECKED : MF_UNCHECKED); } static BOOL Frame_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct) { CLIENTCREATESTRUCT ClientStruct; UINT uTool; ClientStruct.hWindowMenu = GetSubMenu (GetMenu (hwnd), MENU_WINDOW_POS); ClientStruct.idFirstChild = IDM_FIRSTCHILD; hwndClient = CreateWindow (TEXT("MDICLIENT"), NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, (HMENU) 1, hInst, (VOID FAR *) & ClientStruct); if (!hwndClient) return(FALSE); CheckMenuItem(GetMenu(hwnd), nAnnObject, MF_CHECKED); hwndToolBar = MyCreateToolBar(hwnd); L_AnnGetToolBarChecked(hwndToolBar, &uTool); ToolChecked(hwnd, uTool); CheckMenuItem(GetMenu(hwnd), nAnnUserMode, MF_CHECKED); CheckMenuItem(GetMenu(hwnd), IDM_ANNOTATIONTOOLBAR, MF_CHECKED); UpdateMenuNewOptions(hwnd); return(TRUE); } BOOL CALLBACK CloseAll(HWND hwnd, LPARAM lParam) { if (GetWindow (hwnd, GW_OWNER)) return(TRUE); FORWARD_WM_MDIRESTORE (GetParent (hwnd), hwnd, SendMessage); FORWARD_WM_CLOSE (hwnd, SendMessage); return(TRUE); } BOOL CALLBACK SetUserMode(HWND hwnd, LPARAM lParam) { if (GetWindow (hwnd, GW_OWNER)) return(TRUE); { DECLARECHILDDATA(hwnd, pData); L_AnnSetUserMode(pData->hContainer, (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 File"),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 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 ChangeHiliteAndCursors(HANNOBJECT hAutomation, BOOL bAnnHiliteCustom) { L_AnnSetAutoHilightPen(hAutomation, bAnnHiliteCustom ? RGB(0xC0, 0xC0, 0xC0) : RGB(0xFF, 0xFF, 0xFF)); L_AnnSetAutoCursor(hAutomation, ANNAUTOCURSOR_DRAWNEW, bAnnHiliteCustom ? hCursorAnnDrawNew : hCursorDefaultAnnDrawNew); L_AnnSetAutoCursor(hAutomation, ANNAUTOCURSOR_HANDLE, bAnnHiliteCustom ? hCursorAnnHandle : hCursorDefaultAnnHandle); L_AnnSetAutoCursor(hAutomation, ANNAUTOCURSOR_MOVE, bAnnHiliteCustom ? hCursorAnnMove : hCursorDefaultAnnMove); L_AnnSetAutoCursor(hAutomation, ANNAUTOCURSOR_SELECT, bAnnHiliteCustom ? hCursorAnnSelect : hCursorDefaultAnnSelect); } BOOL CALLBACK EnumSetAnnHilite(HWND hwnd, LPARAM lParam) { L_BOOL bAnnHiliteCustom = (L_BOOL)lParam; if (GetWindow (hwnd, GW_OWNER)) return(TRUE); { DECLARECHILDDATA(hwnd, pData); ChangeHiliteAndCursors(pData->hAutomation, bAnnHiliteCustom); } return(TRUE); } static void ChangeAnnotationHilite(L_BOOL bAnnHiliteCustom) { // Change the hilite color for each existing automation object EnumChildWindows(hwndClient, EnumSetAnnHilite, bAnnHiliteCustom); // Change the hilite color for any new automation objects ChangeHiliteAndCursors(NULL, bAnnHiliteCustom); } L_BOOL CALLBACK L_EXPORT ChangeHiliteDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return(TRUE); case WM_COMMAND: switch (CTLID(wParam, lParam)) { case IDOK: case IDCANCEL: EndDialog (hDlg, CTLID(wParam, lParam)); return(TRUE); } } return(FALSE); } BOOL CALLBACK OptionsChanged (HWND hwnd, LPARAM lParam) { DECLARECHILDDATA(hwnd, pData); if (pData) { L_UINT uOptions = (L_UINT)lParam; L_AnnSetOptions(pData->hAutomation, uOptions); } return(TRUE); } void FrameNewOptions(HWND hwnd, L_UINT uMenuItem, HWND hwndClient) { L_BOOL bToolbar = FALSE; L_UINT uOneOption = 0; HWND hwndChild = NULL; L_UINT uOptions = 0; L_UINT32 uNewOptions = 0; L_AnnGetOptions(&uOptions); switch(uMenuItem) { case IDM_NEW_CHECKALL: uOptions = 0; uOneOption = OPTIONS_NEW_ALL; bToolbar = TRUE; break; case IDM_NEW_UNCHECKALL: uOptions = 0; uOneOption = 0; bToolbar = TRUE; break; case IDM_NEW_TOOLBAR: uOneOption = OPTIONS_NEW_TOOLBAR; bToolbar = TRUE; break; case IDM_NEW_METAFILES: uOneOption = OPTIONS_NEW_STAMP_METAFILES; break; case IDM_NEW_ALPHA: uOneOption = OPTIONS_NEW_ALPHA; break; case IDM_NEW_ROTATE: uOneOption = OPTIONS_NEW_ROTATE; break; case IDM_NEW_SIDE_HANDLES: uOneOption = OPTIONS_NEW_SIDE_HANDLES; break; case IDM_NEW_MULTI_SELECT: uOneOption = OPTIONS_NEW_MULTI_SELECT; break; case IDM_NEW_CURSORS: uOneOption = OPTIONS_NEW_CURSORS; break; case IDM_NEW_ESC_CANCEL: uOneOption = OPTIONS_NEW_ESC_CANCEL; break; case IDM_NEW_CALIBRATE_RULER: uOneOption = OPTIONS_NEW_CALIBRATE_RULER; break; case IDM_NEW_DOT_DASH_LINES: uOneOption = OPTIONS_NEW_DOT_DASH_LINES; break; case IDM_NEW_TEXT_OPTIONS: uOneOption = OPTIONS_NEW_TEXT_OPTIONS; break; } if (uOptions & uOneOption) uNewOptions = uOptions & ~uOneOption; else uNewOptions = uOptions | uOneOption; L_AnnSetOptions(NULL, uNewOptions); if (bToolbar) { // destroy the old toolbar, and recreate if( IsWindow(hwndToolBar) ) { DestroyWindow(hwndToolBar); // recreate hwndToolBar = MyCreateToolBar(hwnd); MenuToolChecked(hwnd, nAnnObject); CheckMenuItem(GetMenu(hwnd), IDM_ANNOTATIONTOOLBAR, MF_CHECKED); } } UpdateMenuNewOptions(hwndFrame); EnumChildWindows (hwndClient, OptionsChanged, (LPARAM) uNewOptions); hwndChild = FORWARD_WM_MDIGETACTIVE(hwndClient, SendMessage); if (IsWindow (hwndChild)) InvalidateRect(hwndChild, NULL, FALSE); } static void Frame_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { FARPROC lpfn; HWND hwndChild; switch(id) { case IDM_TOOLSELECT: case IDM_TOOLPOINTER: case IDM_TOOLAUDIO: case IDM_TOOLBUTTON: case IDM_TOOLELLIPSE: case IDM_TOOLFREEHAND: case IDM_TOOLHOTSPOT: case IDM_TOOLLINE: case IDM_TOOLNOTE: case IDM_TOOLPOLYGON: case IDM_TOOLPOLYLINE: case IDM_TOOLRECT: case IDM_TOOLREDACT: case IDM_TOOLSTAMP: case IDM_TOOLTEXT: case IDM_TOOLRTF: case IDM_TOOLHILITE: case IDM_TOOLPUSHPIN: case IDM_TOOLRULER: case IDM_TOOLCROSSPRODUCT: case IDM_TOOLPOINT: case IDM_TOOLPROTRACTOR: case IDM_TOOLFREEHANDHOTSPOT: case IDM_TOOLCURVE: case IDM_TOOLCLOSEDCURVE: case IDM_TOOLENCRYPT: case IDM_TOOLPOLYRULER: case IDM_TOOLTEXTPOINTER: case IDM_TOOLVIDEO: // case IDM_TOOLUSER: case IDM_SUBTOOL_APPROVED: case IDM_SUBTOOL_ASSIGNED: case IDM_SUBTOOL_CHECKED: case IDM_SUBTOOL_CLATPRV: case IDM_SUBTOOL_COPY: case IDM_SUBTOOL_DRAFT: case IDM_SUBTOOL_EXTENDED: case IDM_SUBTOOL_FAX: case IDM_SUBTOOL_FAXED: case IDM_SUBTOOL_IMPORTANT: case IDM_SUBTOOL_INVOICE: case IDM_SUBTOOL_NOTICE: case IDM_SUBTOOL_OFFICIAL: case IDM_SUBTOOL_ONFILE: case IDM_SUBTOOL_PAID: case IDM_SUBTOOL_PASSED: case IDM_SUBTOOL_PENDING: case IDM_SUBTOOL_PROCESSED: case IDM_SUBTOOL_RECEIVED: case IDM_SUBTOOL_REJECTED: case IDM_SUBTOOL_RELEASE: case IDM_SUBTOOL_SENT: case IDM_SUBTOOL_SHIPPED: case IDM_SUBTOOL_TOPSECRET: case IDM_SUBTOOL_URGENT: case IDM_SUBTOOL_VOID: MenuToolChecked(hwnd, id); break; 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); MenuToolChecked(hwnd, nAnnObject); CheckMenuItem(GetMenu(hwnd), IDM_ANNOTATIONTOOLBAR, MF_CHECKED); } break; case IDM_LOCALE_CURRENT: { L_TCHAR *pszMsg; pszMsg = L_AnnSetlocale(LC_ALL, NULL); MessageBox(hwnd, pszMsg, TEXT("Current Locale"), MB_OK); } break; case IDM_LOCALE_ENGLISH: L_AnnSetlocale(LC_ALL, TEXT("English")); break; case IDM_LOCALE_JAPANESE: L_AnnSetlocale(LC_ALL, TEXT("Japanese")); break; case IDM_LOCALE_ARABIC: L_AnnSetlocale(LC_ALL, TEXT("Arabic")); break; case IDM_CHANGE_HILITE: { // Display the dialog box only when enabling the option int nRet = IDOK; if (!gbAnnHiliteCustom) nRet = DoDialogBoxParam(IDD_CHANGE_HILITE, hwnd, (DLGPROC) ChangeHiliteDlgProc, 0); if (nRet == IDOK) { gbAnnHiliteCustom = !gbAnnHiliteCustom; ChangeAnnotationHilite(gbAnnHiliteCustom); } } break; // ********************* New 14.5 options case IDM_NEW_CHECKALL: case IDM_NEW_UNCHECKALL: case IDM_NEW_TOOLBAR: case IDM_NEW_METAFILES: case IDM_NEW_ALPHA: case IDM_NEW_ROTATE: case IDM_NEW_SIDE_HANDLES: case IDM_NEW_MULTI_SELECT: case IDM_NEW_CURSORS: case IDM_NEW_ESC_CANCEL: case IDM_NEW_CALIBRATE_RULER: case IDM_NEW_DOT_DASH_LINES: case IDM_NEW_TEXT_OPTIONS: FrameNewOptions(hwnd, id, hwndClient); 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) { FreeAnnCursors(); L_DlgFree (); PostQuitMessage (0); } static LRESULT Frame_OnLtAnnEvent(HWND hwnd, int id, LPARAM lParam) { switch(id) { case LTANNEVENT_TOOLCHECKED: ToolChecked(hwnd, (UINT) lParam); break; case LTANNEVENT_TOOLDESTROY: hwndToolBar = NULL; CheckMenuItem(GetMenu(hwnd),IDM_ANNOTATIONTOOLBAR,MF_UNCHECKED); break; } return(0); } void Frame_OnInitMenuPopup (HWND hwnd, HMENU hMenu, L_INT item, BOOL fSystemMenu) { HWND hwndChild = FORWARD_WM_MDIGETACTIVE(hwndClient, SendMessage); DECLARECHILDDATA(hwndChild, pData); BOOL fHasChild = IsWindow(hwndChild); 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_SHOWLOCK, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_LOCK, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_UNLOCK, fHasChild ? MF_ENABLED : MF_GRAYED); CheckMenuItem (hMenu, IDM_SHOWLOCK, (fHasChild && pData->fShowLock) ? MF_CHECKED: MF_UNCHECKED); EnableMenuItem(hMenu, IDM_REALIZE_REDACT, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_REALIZE_ALL, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_UNREALIZE, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_APPLY_ENCRYPTORS, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_APPLY_DECRYPTORS, fHasChild ? MF_ENABLED : MF_GRAYED); CheckMenuItem (hMenu, IDM_WANGMODE, gbWangMode ? MF_CHECKED: MF_UNCHECKED); 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); EnableMenuItem(hMenu, IDM_ROTATE90, fHasChild ? MF_ENABLED : MF_GRAYED); EnableMenuItem(hMenu, IDM_MAGGLASS, fHasChild ? MF_ENABLED : MF_GRAYED); CheckMenuItem (hMenu, IDM_MAGGLASS, (fHasChild && pData->bMagGlass) ? MF_CHECKED: MF_UNCHECKED); EnableMenuItem(hMenu, IDM_DOUBLE_BUFFER, fHasChild ? MF_ENABLED : MF_GRAYED); CheckMenuItem (hMenu, IDM_DOUBLE_BUFFER, (fHasChild && pData->bDoubleBuffer) ? MF_CHECKED: MF_UNCHECKED); CheckMenuItem (hMenu, IDM_CHANGE_HILITE, gbAnnHiliteCustom ? 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 L_VOID AddTextTokens(HANNOBJECT hAutomation) { ANNTEXTTOKEN annTextToken; // Add a separator memset(&annTextToken, 0, sizeof(ANNTEXTTOKEN)); annTextToken.uStructSize = sizeof(ANNTEXTTOKEN); annTextToken.nTokenType = ANNTOKEN_SEPARATOR; annTextToken.nReserved = 0; L_AnnInsertTextTokenTable(hAutomation, &annTextToken); // Add a date and user token to automation text dialog annTextToken.uStructSize = sizeof(ANNTEXTTOKEN); annTextToken.cToken = '0'; annTextToken.pszDesc = TEXT("Date: mm/dd/yyyy"); annTextToken.pszTokenString = TEXT("#M/#d/#Y"); annTextToken.nTokenType = ANNTOKEN_TEXT; annTextToken.nReserved = 0; L_AnnInsertTextTokenTable(hAutomation, &annTextToken); // Add a name token annTextToken.uStructSize = sizeof(ANNTEXTTOKEN); annTextToken.cToken = '1'; annTextToken.pszDesc = TEXT("Your Name"); annTextToken.pszTokenString = TEXT("John Smith"); annTextToken.nTokenType = ANNTOKEN_TEXT; annTextToken.nReserved = 0; L_AnnInsertTextTokenTable(hAutomation, &annTextToken); } static BOOL Child_OnCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct) { LPCREATEDATA pCreateData; LPCHILDDATA pData; ANNRECT rc; ANNENCRYPTOPTIONS EncryptOptions; 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; pData->fShowLock = gbShowLockedIcon; pData->bDoubleBuffer = TRUE; pData->hDoubleBuffer = NULL; L_DoubleBufferCreateHandle(&pData->hDoubleBuffer); L_DoubleBufferEnable(pData->hDoubleBuffer, pData->bDoubleBuffer); 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); AddTextTokens(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_AnnShowLockedIcon(pData->hContainer, pData->fShowLock, ANNFLAG_RECURSE|ANNFLAG_NOINVALIDATE); 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); // Note -- do not recurse on container // This removes calibration of rulers! 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); #ifdef WIN32 L_AnnSetAutoOptions(pData->hAutomation, ANNAUTO_TABBEDDIALOG); #endif EncryptOptions.uStructSize = sizeof(ANNENCRYPTOPTIONS); EncryptOptions.uFlags = ANNENCRYPT_ENCRYPT_BITMAP | ANNENCRYPT_SAVE_ENCRYPTOR_KEY | ANNENCRYPT_SAVE_DECRYPTOR_KEY | ANNENCRYPT_CLEAR_ENCRYPTOR_KEY | ANNENCRYPT_CLEAR_DECRYPTOR_KEY; EncryptOptions.nReserved = 0; EncryptOptions.pEncryptBitmap = &pData->Bitmap; EncryptOptions.bSaveEncryptorKey = TRUE; EncryptOptions.bSaveDecryptorKey = TRUE; EncryptOptions.bClearEncryptorKey= FALSE; EncryptOptions.bClearDecryptorKey= FALSE; L_AnnSetEncryptOptions(pData->hAutomation, &EncryptOptions, 0); L_AnnSetEncryptOptions(pData->hContainer, &EncryptOptions, ANNFLAG_RECURSE); // Set new v14.5 rotate options { L_INT nRet=SUCCESS; ANNROTATEOPTIONS RotateOptions; memset(&RotateOptions, 0, sizeof(ANNROTATEOPTIONS)); RotateOptions.uStructSize = sizeof(ANNROTATEOPTIONS); RotateOptions.uFlags = ANNROTATE_SHOW_ROTATE_HANDLES; RotateOptions.bShowRotateHandles = TRUE; RotateOptions.nReserved = 0; nRet = L_AnnSetRotateOptions(pData->hAutomation, &RotateOptions, 0); if (nRet == SUCCESS) { // Cannot save pObject->bShowRotateHandles since v14_5 is mid version // Set all objects in container to have a value of pAutomation->bShowRotateHandles // This is a hack that should be removed in v15, when we can save bShowRotateHandles nRet = L_AnnSetRotateOptions(pData->hContainer, &RotateOptions, ANNFLAG_NOTTHIS | ANNFLAG_RECURSE); } } return(TRUE); } static void Child_OnPaint(HWND hwnd) { DECLARECHILDDATA(hwnd, pData); PAINTSTRUCT ps; HPALETTE hPalette; HDC hMemDC = NULL; BeginPaint (hwnd, &ps); if(pData->Bitmap.Flags.Allocated) { GetClientRect(hwnd, &pData->rcClient); hMemDC = L_DoubleBufferBegin(pData->hDoubleBuffer, ps.hdc, pData->rcClient.right, pData->rcClient.bottom); if(pData->bDoubleBuffer) { HBRUSH hBrush = GetStockObject (GRAY_BRUSH); FillRect(hMemDC, &ps.rcPaint, hBrush); } if (pData->hPalette) hPalette = SelectPalette (hMemDC, pData->hPalette, TRUE); GetWindowRect(hwnd, &pData->rcWindow); L_PaintDC (hMemDC, &pData->Bitmap, NULL, NULL, &pData->rcView, &ps.rcPaint, SRCCOPY); if (pData->hPalette) SelectPalette (hMemDC, hPalette, TRUE); L_AnnDraw(hMemDC, &ps.rcPaint, pData->hContainer); if (hMemDC != ps.hdc) { if(pData->hPalette) { SaveDC(ps.hdc); SelectPalette (ps.hdc, pData->hPalette, TRUE); RealizePalette(ps.hdc); } } L_DoubleBufferEnd(pData->hDoubleBuffer, ps.hdc); if (hMemDC != ps.hdc) RestoreDC(ps.hdc, -1); } 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) { L_DoubleBufferDestroyHandle(pData->hDoubleBuffer); 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); else uTool = MenuToTool(nAnnObject); 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)); if(pData->bMagGlass) L_UpdateMagGlassRect(hwnd, &pData->rcView); } 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)); if(pData->bMagGlass) L_UpdateMagGlassRect(hwnd, &pData->rcView); } BOOL CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static LPTSTR pszPassword; switch (msg) { case WM_INITDIALOG: pszPassword = (LPTSTR) lParam; pszPassword[99] = 0; SendDlgItemMessage(hDlg, IDC_EDIT1, EM_SETPASSWORDCHAR, (WPARAM) '*', 0); return (TRUE); case WM_COMMAND: switch (CTLID(wParam, lParam)) { case IDC_EDIT1: switch (NOTIFYCODE(wParam, lParam)) { case EN_CHANGE: break; } return (TRUE); case IDOK: GetDlgItemText (hDlg, IDC_EDIT1, pszPassword, 100); EndDialog (hDlg, IDOK); return (TRUE); case IDCANCEL: EndDialog (hDlg, IDCANCEL); return (TRUE); } } return (FALSE); } static int GetPassword(HWND hwnd, LPTSTR pszPassword) { switch(DoDialogBoxParam(IDD_PASSWORD, hwnd, (DLGPROC)PasswordDlgProc, (LPARAM)pszPassword)) { case IDOK: return lstrlen(pszPassword); default: return 0; } } 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 = MIN_ZOOM_FACTOR; Parm.nMax = MAX_ZOOM_FACTOR; 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; } L_INT L_EXPORT L_FAR MagGlassOwnerDrawCallback(HWND hWnd, HDC hMemDC, L_INT32 nXPos, L_INT32 nYPos, LPRECT pMagGlass, L_VOID L_FAR *pUserData) { LPCHILDDATA pData = (LPCHILDDATA) pUserData; L_DOUBLE OffsetXOld, OffsetYOld; L_DOUBLE OffsetX, OffsetY; L_DOUBLE ScalarXOld, ScalarYOld; L_DOUBLE ScalarX, ScalarY; L_DOUBLE MagCenterX, MagCenterY; L_DOUBLE BitmapX, BitmapY; L_DOUBLE MagDestX, MagDestY; RECT rc; L_AnnPushFixedState(pData->hContainer, ANNFLAG_RECURSE | ANNFLAG_NOINVALIDATE); L_AnnGetOffsetX(pData->hContainer, &OffsetXOld); L_AnnGetOffsetY(pData->hContainer, &OffsetYOld); L_AnnGetScalarX(pData->hContainer, &ScalarXOld); L_AnnGetScalarY(pData->hContainer, &ScalarYOld); MagCenterX = nXPos; MagCenterY = nYPos; BitmapX = (L_DOUBLE)(MagCenterX-pData->rcView.left)/((L_DOUBLE)RECTWIDTH(&pData->rcView) /(L_DOUBLE)BITMAPWIDTH(&pData->Bitmap)); BitmapY = (L_DOUBLE)(MagCenterY-pData->rcView.top) /((L_DOUBLE)RECTHEIGHT(&pData->rcView)/(L_DOUBLE)BITMAPHEIGHT(&pData->Bitmap)); MagDestX = BitmapX * ((L_DOUBLE)RECTWIDTH(&pData->rcView) /(L_DOUBLE)BITMAPWIDTH(&pData->Bitmap)) * ((L_DOUBLE)pData->nMagZoom/100.0f); MagDestY = BitmapY * ((L_DOUBLE)RECTHEIGHT(&pData->rcView)/(L_DOUBLE)BITMAPHEIGHT(&pData->Bitmap)) * ((L_DOUBLE)pData->nMagZoom/100.0f); OffsetX = ((L_DOUBLE)RECTWIDTH(pMagGlass) /2.0f) - MagDestX; OffsetY = ((L_DOUBLE)RECTHEIGHT(pMagGlass)/2.0f) - MagDestY; ScalarX = (L_DOUBLE)RECTWIDTH(&pData->rcView) / (L_DOUBLE)BITMAPWIDTH(&pData->Bitmap) * ((L_DOUBLE)pData->nMagZoom/100.0f); ScalarY = (L_DOUBLE)RECTHEIGHT(&pData->rcView) / (L_DOUBLE)BITMAPHEIGHT(&pData->Bitmap) * ((L_DOUBLE)pData->nMagZoom/100.0f); L_AnnSetOffsetX(pData->hContainer, OffsetX, ANNFLAG_NOINVALIDATE); L_AnnSetOffsetY(pData->hContainer, OffsetY, ANNFLAG_NOINVALIDATE); L_AnnSetScalarX(pData->hContainer, ScalarX, ANNFLAG_NOINVALIDATE); L_AnnSetScalarY(pData->hContainer, ScalarY, ANNFLAG_NOINVALIDATE); SetRect(&rc, 0, 0, pData->nMagWidth, pData->nMagHeight); L_AnnDraw(hMemDC, &rc, pData->hContainer); L_AnnSetOffsetX(pData->hContainer, OffsetXOld, ANNFLAG_NOINVALIDATE); L_AnnSetOffsetY(pData->hContainer, OffsetYOld, ANNFLAG_NOINVALIDATE); L_AnnSetScalarX(pData->hContainer, ScalarXOld, ANNFLAG_NOINVALIDATE); L_AnnSetScalarY(pData->hContainer, ScalarYOld, ANNFLAG_NOINVALIDATE); L_AnnPopFixedState(pData->hContainer, ANNFLAG_RECURSE | ANNFLAG_NOINVALIDATE); return SUCCESS; } static void MyStartMagGlass(HWND hwnd, LPCHILDDATA pData) { MAGGLASSOPTIONS Options; L_AnnSetActiveState(pData->hAutomation, ANNACTIVE_DISABLED); //pData->nMagWidth = 150; //pData->nMagHeight = 100; //pData->nMagZoom = 400; pData->nMagWidth = 200; pData->nMagHeight = 200; pData->nMagZoom = 200; Options.uStructSize = sizeof(MAGGLASSOPTIONS); Options.nWidth = pData->nMagWidth; Options.nHeight = pData->nMagHeight; Options.nZoom = pData->nMagZoom; Options.clrPen = RGB(0,0,0); Options.hMagCursor = NULL; Options.clrBack = RGB(128,128,128); Options.bEllipse = FALSE; Options.nBorderSize = 1; Options.b3D = FALSE; Options.uPaintFlags = 0; Options.pMask = NULL; Options.uMaskCount = 0; Options.uMagGlassFlags = CROSSHAIR_FINE; Options.nCrosshair = 1; Options.bIgnoreRgn = TRUE; Options.bCenter = TRUE; L_StartMagGlass( hwnd, &pData->Bitmap, &pData->rcView, &Options, NULL, pData); L_SetMagGlassOwnerDrawCallback(hwnd, MagGlassOwnerDrawCallback, pData); pData->bMagGlass = TRUE; } static void Child_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { DECLARECHILDDATA(hwnd, pData); HCURSOR hCursor; HDC hDC; RECT rc; L_TCHAR szPassword[100]; switch(id) { 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_PrintBitmap 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: { L_INT nZoomFactor; nZoomFactor = GetZoomFactor (hwnd, pData->nZoom); if ((nZoomFactor >= MIN_ZOOM_FACTOR) && (nZoomFactor <= MAX_ZOOM_FACTOR)) { pData->fFitImage = FALSE; SetZoomFactor (hwnd, nZoomFactor); Child_SizeChange (hwnd, TRUE); } } break; case IDM_FITIMAGE: pData->fFitImage = TRUE; pData->nZoom = 100; Child_SizeChange(hwnd, TRUE); break; case IDM_DOUBLE_BUFFER: pData->bDoubleBuffer = !pData->bDoubleBuffer; L_DoubleBufferEnable(pData->hDoubleBuffer, pData->bDoubleBuffer); break; case IDM_ROTATE90: { L_DOUBLE xCenter = (L_DOUBLE)BITMAPWIDTH(&pData->Bitmap) / 2; L_DOUBLE yCenter = (L_DOUBLE)BITMAPHEIGHT(&pData->Bitmap) / 2; ANNPOINT annPoint; ANNRECT newRect; // Stop the magnifying glass if (pData->bMagGlass) L_StopMagGlass(hwnd); L_RotateBitmap(&pData->Bitmap, 9000, ROTATE_RESIZE, RGB(0,0,0)); //pData->fFitImage = FALSE; //pData->nZoom = 100; Child_SizeChange (hwnd, TRUE); /* reset ann container rect */ newRect.left = 0; newRect.top = 0; newRect.right = BITMAPWIDTH(&pData->Bitmap); newRect.bottom = BITMAPHEIGHT(&pData->Bitmap); L_AnnSetRect(pData->hContainer, &newRect); /* rotate annotations */ annPoint.x = (L_DOUBLE)xCenter; annPoint.y = (L_DOUBLE)yCenter; L_AnnRotate(pData->hContainer, 90, &annPoint, ANNFLAG_NOTCONTAINER | ANNFLAG_RECURSE); L_AnnMove(pData->hContainer, (L_DOUBLE)BITMAPWIDTH(&pData->Bitmap) / 2 - (L_DOUBLE)xCenter, (L_DOUBLE)BITMAPHEIGHT(&pData->Bitmap) / 2 - (L_DOUBLE)yCenter, ANNFLAG_NOTCONTAINER | ANNFLAG_RECURSE); if (pData->bMagGlass) MyStartMagGlass(hwnd, pData); } break; case IDM_LOCK: case IDM_UNLOCK: if(GetPassword(hwnd, szPassword)) { if(id == IDM_LOCK) L_AnnLock(pData->hContainer, szPassword, ANNFLAG_RECURSE | ANNFLAG_SELECTED); else L_AnnUnlock(pData->hContainer, szPassword, ANNFLAG_RECURSE); } break; case IDM_SHOWLOCK: gbShowLockedIcon = pData->fShowLock = !pData->fShowLock; L_AnnShowLockedIcon(pData->hContainer, pData->fShowLock, ANNFLAG_RECURSE); break; case IDM_REALIZE_REDACT: case IDM_REALIZE_ALL: L_AnnRealize(&pData->Bitmap, NULL, pData->hContainer, id == IDM_REALIZE_REDACT); break; case IDM_UNREALIZE: if(L_AnnUnrealize(&pData->Bitmap, NULL, pData->hContainer, FALSE) == ERROR_ANN_LOCKED) MessageBox(hwnd, TEXT("Some redact objects are locked and cannot be restored"), TEXT("Warning"), MB_OK); break; case IDM_APPLY_ENCRYPTORS: L_AnnEncryptApply(pData->hContainer, ANNENCRYPTAPPLY_ENCRYPTOR, ANNFLAG_RECURSE); break; case IDM_APPLY_DECRYPTORS: L_AnnEncryptApply(pData->hContainer, ANNENCRYPTAPPLY_DECRYPTOR, ANNFLAG_RECURSE); break; case IDM_WANGMODE: gbWangMode = !gbWangMode; break; case IDM_MAGGLASS: if(pData->bMagGlass) { L_StopMagGlass(hwnd); pData->bMagGlass = FALSE; L_AnnSetActiveState(pData->hAutomation, ANNACTIVE_ENABLED); } else { MyStartMagGlass(hwnd, pData); } } } 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); if (pData->bDoubleBuffer) { InvalidateRect(hwnd, NULL, FALSE); } else // scroll window only if no fixed objects in view { RECT rcClient; L_BOOL bFixedInRect = FALSE; GetClientRect(hwnd, &rcClient); L_AnnIsFixedInRect(pData->hContainer, &rcClient, &bFixedInRect, ANNFLAG_RECURSE); if (bFixedInRect) InvalidateRect(hwnd, NULL, FALSE); else ScrollWindow (hwnd, 0, -nScrollInc, NULL, NULL); } SetScrollPos (hwnd, SB_VERT, pData->nVScrollPos, TRUE); UpdateWindow (hwnd); } pData->fInScroll = FALSE; if(pData->bMagGlass) L_UpdateMagGlassRect(hwnd, &pData->rcView); } 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); if (pData->bDoubleBuffer) { InvalidateRect(hwnd, NULL, FALSE); } else // scroll window only if no fixed objects in view { RECT rcClient; L_BOOL bFixedInRect = FALSE; GetClientRect(hwnd, &rcClient); L_AnnIsFixedInRect(pData->hContainer, &rcClient, &bFixedInRect, ANNFLAG_RECURSE); if (bFixedInRect) InvalidateRect(hwnd, NULL, FALSE); else ScrollWindow (hwnd, -nScrollInc, 0, NULL, NULL); } SetScrollPos (hwnd, SB_HORZ, pData->nHScrollPos, TRUE); UpdateWindow (hwnd); } pData->fInScroll = FALSE; if(pData->bMagGlass) L_UpdateMagGlassRect(hwnd, &pData->rcView); } static BOOL Child_OnEraseBkgnd (HWND hwnd, HDC hdc) { HGDIOBJ hBrush; HRGN hClientRgn, hFillRgn; RECT rcView, rcClient; DECLARECHILDDATA(hwnd, pData); if(!pData->bDoubleBuffer) { 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); } // When creating rectangles/ellipses keeping the shift key pressed, this function will // make sure we are creating squares/circles. // When we create lines/pointers, this function will create horizontal or vertical lines/pointers. static void AnnCheckMouse(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { //The commented code below illustrates how you can modify the behavior of the annotation tools //It has been commented out because the behavior below is now part of the annotation automation return; /* L_INT dx, dy; L_UINT uTool; // If the current tool is user tool, create two annotation objects: an ellipse inside a rectangle L_AnnGetToolBarChecked(hwndToolBar, &uTool); if(pMousePos->uKeyFlags & MK_SHIFT) switch(uTool) { case ANNTOOL_RECT: case ANNTOOL_ELLIPSE: // restrict the mouse position to form square objects and circles if the shift key is down dx = abs(pMousePos->pt.x - pData->pt0.x); dy = abs(pMousePos->pt.y - pData->pt0.y); if(dx < dy) { // adjust the x position by dx - dy if(pMousePos->pt.x > pData->pt0.x) pMousePos->pt.x -= dx - dy; else pMousePos->pt.x += dx - dy; } else if(dx > dy) { // adjust the y position by dy - dx if(pMousePos->pt.y > pData->pt0.y) pMousePos->pt.y -= dy - dx; else pMousePos->pt.y += dy - dx; } break; case ANNTOOL_LINE: case ANNTOOL_POINTER: // restrict the mouse position to form vertical or horizontal objects if the shift key is down dx = abs(pMousePos->pt.x - pData->pt0.x); dy = abs(pMousePos->pt.y - pData->pt0.y); if(dx > dy) pMousePos->pt.y = pData->pt0.y; // horizontal lines else pMousePos->pt.x = pData->pt0.x; // vertical lines break; } */ } LRESULT Child_OnLtAnnEvent(HWND hwnd, int id, LPARAM lParam) { L_UINT uType; L_UINT32 uTag; DECLARECHILDDATA(hwnd, pData); L_TCHAR s[50]; L_UINT uSelected; switch(id) { case LTANNEVENT_INSERT: L_AnnGetType((HANNOBJECT) lParam, &uType); if( uType == ANNOBJECT_BUTTON ) L_AnnSetTag((HANNOBJECT) lParam, ++uNextTag, 0); else if (uType == ANNOBJECT_HOTSPOT || uType == ANNOBJECT_FREEHANDHOTSPOT) L_AnnSetTag((HANNOBJECT) lParam, ++uNextTag, 0); break; case LTANNEVENT_AUTOCLICKED: L_AnnGetType((HANNOBJECT) lParam, &uType); L_AnnGetTag((HANNOBJECT) lParam, &uTag); if(uType == ANNOBJECT_BUTTON) { wsprintf(s, TEXT("Button with tag %lu was clicked"), uTag); MessageBox(hwnd, s, TEXT("Event"), MB_OK); } else if(uType == ANNOBJECT_HOTSPOT || uType == ANNOBJECT_FREEHANDHOTSPOT) { wsprintf(s, TEXT("HotSpot with tag %lu was clicked"), uTag); MessageBox(hwnd, s, TEXT("Event"), MB_OK); } break; case LTANNEVENT_AUTOENDSET: L_AnnSetToolBarChecked(hwndToolBar, ANNTOOL_SELECT); ToolChecked(hwndFrame, ANNTOOL_SELECT); break; case LTANNEVENT_HYPERLINKMENU: GetHyperlink (hwnd, (HANNOBJECT)lParam, pData); break; case LTANNEVENT_HYPERLINK: MessageBox(hwnd, TEXT("Object's hyperlink has been activated!"), TEXT("WM_LTANNEVENT"), MB_OK); break; case LTANNEVENT_LBUTTONDOWN: pData->fLeftButtonDown = TRUE; pData->pt0 = ((pANNMOUSEPOS)lParam)->pt; break; case LTANNEVENT_MOUSEMOVE: if(pData->fLeftButtonDown) AnnCheckMouse(pData, (pANNMOUSEPOS)lParam); break; case LTANNEVENT_LBUTTONUP: if(pData->fLeftButtonDown) { AnnCheckMouse(pData, (pANNMOUSEPOS)lParam); pData->fLeftButtonDown = FALSE; } break; case LTANNEVENT_MENU: // add the Flip menu only if we have one object selected L_AnnGetSelectCount(pData->hContainer, &uSelected); if(uSelected >= 1) { AppendMenu((HMENU)lParam, MF_SEPARATOR, 0, NULL); AppendMenu((HMENU)lParam, MF_ENABLED|MF_STRING, LTANNEVENT_MENUFIRST, TEXT("&Flip")); } break; case LTANNEVENT_MENUFIRST: if(pData->hAutomation == (HANNOBJECT)lParam) // flip all the selected objects L_AnnFlip(pData->hContainer, NULL, ANNFLAG_RECURSE|ANNFLAG_SELECTED); else // flip the selected object L_AnnFlip((HANNOBJECT)lParam, NULL, 0); break; } return(0); } L_TCHAR *szObjectTypes[] = { TEXT("CONTAINER"), TEXT("POINTER"), TEXT("AUDIO"), TEXT("BUTTON"), TEXT("ELLIPSE"), TEXT("FREEHAND"), TEXT("HILITE"), TEXT("HOTSPOT"), TEXT("LINE"), TEXT("NOTE"), TEXT("POLYGON"), TEXT("POLYLINE"), TEXT("RECT"), TEXT("REDACT"), TEXT("STAMP"), TEXT("TEXT"), TEXT("AUTOMATION") }; LRESULT Child_OnUserMsg(HWND hwnd, int id, LPARAM lParam) { L_TCHAR s[50]; HANNOBJECT hObject = (HANNOBJECT)lParam; L_UINT uType; if(L_AnnGetType(hObject, &uType) == SUCCESS) { if(uType < sizeof(szObjectTypes) / sizeof(szObjectTypes[0])) wsprintf(s, TEXT("Object type = %s, wParam = %d"), (LPTSTR)szObjectTypes[uType], id); else wsprintf(s, TEXT("Object type = Unknown(%d), wParam = %d"), uType, id); } else wsprintf(s, TEXT("Unknown object - cannot get the type, wParam = %d"), id); MessageBox(hwnd, s, TEXT("HYPERLINK USER MESSAGE"), MB_OK); return(0); } void Child_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) { L_UINT uTool; DECLARECHILDDATA(hwnd, pData); // If the current tool is user tool, create two annotation objects: an ellipse inside a rectangle L_AnnGetToolBarChecked(hwndToolBar, &uTool); if(uTool == ANNTOOL_USER) { POINT pt; L_AnnCreateItem(pData->hContainer, ANNOBJECT_RECT, TRUE, &pData->hRect); L_AnnCreateItem(pData->hContainer, ANNOBJECT_ELLIPSE, TRUE, &pData->hEllipse); pt.x = x; pt.y = y; L_AnnDefine(pData->hRect, &pt, ANNDEFINE_BEGINSET); L_AnnDefine(pData->hEllipse, &pt, ANNDEFINE_BEGINSET); pData->fCapture = TRUE; } } void Child_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags) { DECLARECHILDDATA(hwnd, pData); if(pData->fCapture) { POINT pt; pt.x = x; pt.y = y; L_AnnDefine(pData->hRect, &pt, ANNDEFINE_APPEND); L_AnnDefine(pData->hEllipse, &pt, ANNDEFINE_APPEND); } } void Child_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags) { DECLARECHILDDATA(hwnd, pData); if(pData->fCapture) { POINT pt; pt.x = x; pt.y = y; L_AnnDefine(pData->hRect, &pt, ANNDEFINE_END); L_AnnDefine(pData->hEllipse, &pt, ANNDEFINE_END); pData->fCapture = FALSE; // set the new objects to be selected and set the default annotation properties L_AnnSetSelected(pData->hContainer, FALSE, ANNFLAG_RECURSE); L_AnnSetSelected(pData->hRect, TRUE, 0); L_AnnSetSelected(pData->hEllipse, TRUE, 0); // set the default settings from the automation object L_AnnSetAutoDefaults(pData->hAutomation, pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE); pData->hRect = pData->hEllipse = NULL; // set the toolbar tool to be ANNTOOL_SELECT to mimic what the other tools do L_AnnSetToolBarChecked(hwndToolBar, ANNTOOL_SELECT); ToolChecked(hwndFrame, ANNTOOL_SELECT); L_AnnGroup(pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE, NULL); } } static VOID Child_OnKeyDown(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT flags) { DECLARECHILDDATA(hWnd, pData); if (fDown) { switch (vk) { case VK_ESCAPE: //FORWARD_WM_KEYDOWN(hWnd, vk, cRepeat, flags, SendMessage); break; case VK_HOME: FORWARD_WM_VSCROLL (hWnd, 0, SB_TOP, 0, SendMessage); break; case VK_END: FORWARD_WM_VSCROLL (hWnd, 0, SB_BOTTOM, 0, SendMessage); break; case VK_PRIOR: FORWARD_WM_VSCROLL (hWnd, 0, SB_PAGEUP, 0, SendMessage); break; case VK_NEXT: FORWARD_WM_VSCROLL (hWnd, 0, SB_PAGEDOWN, 0, SendMessage); break; case VK_UP: FORWARD_WM_VSCROLL (hWnd, 0, SB_LINEUP, 0, SendMessage); break; case VK_DOWN: FORWARD_WM_VSCROLL (hWnd, 0, SB_LINEDOWN, 0, SendMessage); break; case VK_LEFT: FORWARD_WM_HSCROLL (hWnd, 0, SB_LINELEFT, 0, SendMessage); break; case VK_RIGHT: FORWARD_WM_HSCROLL (hWnd, 0, SB_LINERIGHT, 0, SendMessage); break; case 0xBB: //VK_OEM_PLUS: { pData->fFitImage = FALSE; if (pData->nZoom < MAX_ZOOM_FACTOR) { SetZoomFactor (hWnd, pData->nZoom+1); Child_SizeChange (hWnd, TRUE); } } break; case 0xBD: //VK_OEM_MINUS: { pData->fFitImage = FALSE; if (pData->nZoom > MIN_ZOOM_FACTOR) { SetZoomFactor (hWnd, pData->nZoom-1); Child_SizeChange (hWnd, TRUE); } } break; } } return; } 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_USERMSG, Child_OnUserMsg); HANDLE_MSG (hwnd, WM_LBUTTONDOWN, Child_OnLButtonDown); HANDLE_MSG (hwnd, WM_MOUSEMOVE, Child_OnMouseMove); HANDLE_MSG (hwnd, WM_LBUTTONUP, Child_OnLButtonUp); HANDLE_MSG(hwnd, WM_KEYDOWN, Child_OnKeyDown); } return(DefMDIChildProc (hwnd, msg, wParam, lParam)); } static SAVEDLGPARAMS FSParm; static OPENFILENAME SaveFileName; /* This function will get the save options filled by the Save dialog into a SAVEFILEOPTION structure to be used by the Save functions */ 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; } if((pFSParm->nFormat == FILE_J2K)|| (pFSParm->nFormat == FILE_JP2)|| (pFSParm->nFormat == FILE_CMW)|| (pFSParm->nFormat == FILE_TIF_J2K)|| (pFSParm->nFormat == FILE_TIF_CMW)) { L_SetJ2KOptions(&FSParm.FileJ2KOptions); } pSaveFileOption->Flags |= ESO_JPEGSTAMP; /* force compressed stamps */ } static void SaveBitmap(HWND hwnd) { DECLARECHILDDATA(hwnd, pData); HCURSOR hCursor; L_TCHAR szFile[L_MAXPATH]=TEXT(""); L_INT nRet; _fmemset(&SaveFileName, 0, sizeof(OPENFILENAME)); _fmemset(&FSParm, 0, sizeof(SAVEDLGPARAMS)); FSParm.uStructSize = sizeof (SAVEDLGPARAMS); FSParm.uDlgFlags = DLG_SAVE_SHOW_FILEOPTIONS_PROGRESSIVE | DLG_SAVE_SHOW_FILEOPTIONS_MULTIPAGE | DLG_SAVE_SHOW_FILEOPTIONS_STAMP | DLG_SAVE_SHOW_FILEOPTIONS_QFACTOR | DLG_SAVE_SHOW_FILEOPTIONS_BASICJ2KOPTIONS| DLG_SAVE_SHOW_FILEOPTIONS_J2KOPTIONS; 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)/sizeof(L_TCHAR); 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, (gbWangMode ? ANNFMT_WANGTAG : 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_XML, FALSE, NULL); } SetCursor (hCursor); } } /*====(SetSavePageNumber)====================================================== Description: Sets the page number for multipage file access. Syntax : L_VOID SetSavePageNumber(L_INT nPage) Prototype : annotate.h Parameters : pSaveParm Structure contsining the save parameters. Return Value: None. ==========================================================================*/ L_VOID SetSavePageNumber(LPSAVEDLGPARAMS pSaveParm) { switch(pSaveParm->uSaveMulti) { case MULTIPAGE_OPERATION_OVERWRITE: SaveFileOption.PageNumber = 1; break; case MULTIPAGE_OPERATION_APPEND: SaveFileOption.PageNumber = 2; break; case MULTIPAGE_OPERATION_REPLACE: SaveFileOption.PageNumber = pSaveParm->nPageNumber; SaveFileOption.Flags |= ESO_REPLACEPAGE; break; case MULTIPAGE_OPERATION_INSERT: SaveFileOption.PageNumber = pSaveParm->nPageNumber; SaveFileOption.Flags |= ESO_INSERTPAGE; break; } return; } /*====(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. ==========================================================================*/ L_BOOL CALLBACK L_EXPORT AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return(TRUE); case WM_COMMAND: switch (CTLID(wParam, lParam)) { case IDOK: case IDCANCEL: EndDialog (hDlg, 0); return(TRUE); } } return(FALSE); } L_BOOL CALLBACK L_EXPORT HyperlinkDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static LPHYPERLINKPARM pParm; switch (message) { case WM_INITDIALOG: pParm = (LPHYPERLINKPARM) lParam; CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO5, IDC_RADIO1 + pParm->uType); if(pParm->uType == ANNLINK_RUN) SetDlgItemText(hDlg, IDC_EDIT1, pParm->Buffer); else if(pParm->uType == ANNLINK_WEBPAGE) SetDlgItemText(hDlg, IDC_EDIT2, pParm->Buffer); EnableWindow(GetDlgItem(hDlg, IDC_EDIT1), pParm->uType == ANNLINK_RUN); EnableWindow(GetDlgItem(hDlg, IDC_BUTTON1), pParm->uType == ANNLINK_RUN); EnableWindow(GetDlgItem(hDlg, IDC_EDIT2), pParm->uType == ANNLINK_WEBPAGE); return (TRUE); case WM_COMMAND: switch (CTLID(wParam, lParam)) { case IDC_RADIO1: case IDC_RADIO2: case IDC_RADIO3: case IDC_RADIO4: case IDC_RADIO5: switch(NOTIFYCODE(wParam, lParam)) { case BN_CLICKED: EnableWindow(GetDlgItem(hDlg, IDC_EDIT1), CTLID(wParam, lParam) == IDC_RADIO4); EnableWindow(GetDlgItem(hDlg, IDC_BUTTON1), CTLID(wParam, lParam) == IDC_RADIO4); EnableWindow(GetDlgItem(hDlg, IDC_EDIT2), CTLID(wParam, lParam) == IDC_RADIO5); break; } break; case IDOK: if(IsDlgButtonChecked(hDlg, IDC_RADIO1) == BST_CHECKED) pParm->uType = ANNLINK_NONE; else if(IsDlgButtonChecked(hDlg, IDC_RADIO2) == BST_CHECKED) pParm->uType = ANNLINK_LTANNEVENT; else if(IsDlgButtonChecked(hDlg, IDC_RADIO3) == BST_CHECKED) { pParm->uType = ANNLINK_USERMSG; pParm->uMsg = WM_USERMSG; /* set a user message and a wParam */ pParm->wParam = 0; } else if(IsDlgButtonChecked(hDlg, IDC_RADIO4) == BST_CHECKED) { pParm->uType = ANNLINK_RUN; GetDlgItemText(hDlg, IDC_EDIT1, pParm->Buffer, sizeof(pParm->Buffer)); if(!pParm->Buffer[0]) { SetFocus (GetDlgItem (hDlg, IDC_EDIT1)); return TRUE; } } else if(IsDlgButtonChecked(hDlg, IDC_RADIO5) == BST_CHECKED) { pParm->uType = ANNLINK_WEBPAGE; GetDlgItemText(hDlg, IDC_EDIT2, pParm->Buffer, sizeof(pParm->Buffer)); if(!pParm->Buffer[0]) { SetFocus (GetDlgItem (hDlg, IDC_EDIT2)); return TRUE; } } else /* one of the type buttons has to be checked!! */ { return TRUE; } EndDialog (hDlg, IDOK); return (TRUE); case IDCANCEL: EndDialog (hDlg, IDCANCEL); return (TRUE); } } return (FALSE); } static int GetHyperlink (HWND hWnd, HANNOBJECT hObject, LPCHILDDATA pData) { HYPERLINKPARM Parm; L_INT nRet; nRet = L_AnnGetHyperlink(hObject, &Parm.uType, &Parm.uMsg, &Parm.wParam, &Parm.Buffer[0]); if(nRet != SUCCESS) return nRet; switch (DoDialogBoxParam (IDD_HYPERLINK, hWnd, (DLGPROC) HyperlinkDlgProc, (LPARAM) (LPHYPERLINKPARM) &Parm)) { case IDOK: /* hObject is pData->hAutomation in one or two cases: a) there are no objects selected and you want to change the default properties of the objects that will be created or b) there are 2 or more objects that are selected and whose Hyperlinks need to be changed otherwise (if there is only one object selected) hObject is the handle of the selected object I change the automation object as well as the selected object(s) so that the newly created objects will have the same hyperlink as the last object's Hyperlink. If you don't want this, remove the line with L_AnnSetHyperlink(pData->hAutomation... */ if(hObject == pData->hAutomation) /* change the automation object and all selected objects */ { L_AnnSetHyperlink(pData->hAutomation, Parm.uType, Parm.uMsg, Parm.wParam, Parm.Buffer, 0); nRet = L_AnnSetHyperlink(pData->hContainer, Parm.uType, Parm.uMsg, Parm.wParam, Parm.Buffer, ANNFLAG_RECURSE|ANNFLAG_SELECTED); } else /* change the automation object and the selected object */ { L_AnnSetHyperlink(pData->hAutomation, Parm.uType, Parm.uMsg, Parm.wParam, Parm.Buffer, 0); nRet = L_AnnSetHyperlink(hObject, Parm.uType, Parm.uMsg, Parm.wParam, Parm.Buffer, 0); } return nRet; case IDCANCEL: default: break; } return (SUCCESS); } /*---[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; }