/*[]=====================================================================[]*/ /*[] LEADTOOLS for Windows - Version 11 []*/ /*[] []*/ /*[] []*/ /*[] Copyright (c) 1991-2000 LEAD Technologies, Inc. []*/ /*[] All Rights Reserved. []*/ /*[]=====================================================================[]*/ /*---(Draw)---------------------------------------------------------------- LEAD Functions Used. L_CreateLeadDC L_DeleteLeadDC L_CreatePaintPalette L_PaintDC L_FreeBitmap L_FileInfo L_InitBitmap L_LoadFile L_SaveBitmap L_CombineBitmap L_SetBitmapRgnRect L_SetBitmapRgnRoundRect L_SetBitmapRgnEllipse L_SetBitmapRgnPolygon L_SetBitmapRgnHandle L_BitmapHasRgn L_FreeBitmapRgn L_FlipBitmap L_RotateBitmapFine L_ReverseBitmap L_SizeBitmap L_ResampleBitmap L_ChangeBitmapIntensity L_ChangeBitmapContrast L_GetBitmapRgnHandle L_DupPalette L_ConvertToDDB L_FrameBitmapRgn L_CopyBitmapRect L_CopyBitmap L_SetBitmapRgnColor L_OffsetBitmapRgn L_IsPtInBitmapRgn We have made the assumption that the user has the knowledge of programing in C and Windows. This is a menu driven example that will show some of the drawing capabilities available with the LEADTOOLS DLL for Windows Toolkit. Usage: DRAW --------------------------------------------------------------------------*/ #include "Windows.h" #include "Windowsx.h" #include "tchar.h" #include #include #include #include #include #include /* for sprintf */ #include "..\\..\\..\\include\\l_bitmap.h" /* LEADTOOLS main header file. */ #include "..\\..\\..\\include\\l_error.h" /* LEADTOOLS error definition header file. */ #include "draw.h" /* Program specific header file. */ /* the combine flag that copies the source into the destination */ #define L_SRCCOPY (CB_DST_0 | CB_OP_OR) #ifdef WIN32 #define MoveTo(hdc, x, y) MoveToEx(hdc, x, y, NULL) #else HINSTANCE hDibDrv; #endif L_BOOL ExtractCommandData ( ) ; /*---[WinMain]--------------------------------------------------------------- Syntax: L_INT L_PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) Parameters: hInstance Current instance. hPrevInstance previous instance. lpCmdLine command line. nCmdShow show-window type. Prototype: Windows.h Notes: Windows main function, calls initialization function and processes message loop. --------------------------------------------------------------------------*/ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; /* Message structure, See Windows SDK for more information. */ UNLOCKSUPPORT(); if (!hPrevInstance) /* Other instances of app running? */ if (!InitApplication (hInstance)) /* Initialize shared things. */ return (FALSE); /* Exits if unable to initialize. */ ExtractCommandData ( ) ; if (!InitInstance (hInstance, nCmdShow)) /* Do instance initializations. */ return (FALSE); #ifndef WIN32 hDibDrv = LoadLibrary ("LTVDD11w.DRV"); if (hDibDrv < 32) return (FALSE); #endif L_DlgInit(DLG_INIT_COLOR); /* Acquire and dispatch messages until a WM_QUIT message is received. */ while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); /* Translates virtual key codes. */ DispatchMessage (&msg); /* Dispatches message to window. */ } L_DlgFree(); #ifndef WIN32 if ((L_UINT) hDibDrv >= 32) FreeLibrary (hDibDrv); #endif DeleteObject( hcrHand ); DeleteObject( hcrEyeDrop ); return (msg.wParam); /* Returns the value from PostQuitMessage. */ } /*---[InitApplication]------------------------------------------------------ Syntax: L_BOOL InitApplication( HANDLE hInstance ) Parameters: hInstance Current instance. Prototype: Draw.h Notes: Initializes window class structure and registers window class. --------------------------------------------------------------------------*/ L_BOOL InitApplication (HANDLE hInstance) { WNDCLASS wcWindowClass; hInstApp = hInstance; wcWindowClass.style = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */ wcWindowClass.lpfnWndProc = MainWndProc; /* Function to retrieve messages */ /* for windows of this class. */ wcWindowClass.cbClsExtra = 0;/* No per-class extra data. */ wcWindowClass.cbWndExtra = 0;/* No per-window extra data. */ wcWindowClass.hInstance = hInstance; /* Owner. */ wcWindowClass.hIcon = LoadIcon (hInstance, TEXT("LEAD")); wcWindowClass.hCursor = LoadCursor (NULL, IDC_ARROW); wcWindowClass.hbrBackground = GetStockObject (GRAY_BRUSH); wcWindowClass.lpszMenuName = TEXT("MAIN_MENU"); /* Menu. */ wcWindowClass.lpszClassName = TEXT("LEADWClass"); /* Name. */ /* Register the window class and return the result code. */ return (RegisterClass (&wcWindowClass)); } /*---[InitInstance]---------------------------------------------------------- Syntax: L_BOOL InitInstance( HANDLE hInstance, L_INT nCmdShow ) Parameters: hInstance Current instance. nCmdShow Param for first ShowWindow() call. Prototype: Draw.h Notes: Creates main window. --------------------------------------------------------------------------*/ L_BOOL InitInstance (HANDLE hInstance, L_INT nCmdShow) { HWND hWnd; /* Window handle. */ /* Create a main window for this application instance. */ hWnd = CreateWindow ( TEXT("LEADWClass"), TEXT("LEADTOOLS Sample Application"), /* Window title */ WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, /* Window style. */ CW_USEDEFAULT, /* Default horizontal position. */ CW_USEDEFAULT, /* Default vertical position. */ 400, /* Window width. */ 400, /* Window height. */ NULL, /* Overlapped windows have no parent. */ NULL, /* Use the window class menu. */ hInstance, /* This instance owns this window. */ NULL /* Pointer not needed. */ ); if (hWnd == NULL) return (FALSE); /* If window could not be created, return "failure". */ ShowWindow (hWnd, nCmdShow); /* Show the window. */ UpdateWindow (hWnd); /* Send WM_PAINT message. */ hcrHand = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_HAND)); hcrEyeDrop = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_EYEDROP)); return (TRUE); } /*---[MainWndProc]----------------------------------------------------------- Syntax: L_INT32 EXT_FUNCTION MainWndProc( HWND hWnd, L_UINT message, WPARAM wParam, LPARAM lParam ) Parameters: hWnd Window handle. message Type of message. wParam Additional information. lParam Additional information. Prototype: Draw.h Notes: This procedure is responsible for handling window messages. --------------------------------------------------------------------------*/ L_INT32 EXT_FUNCTION MainWndProc (HWND hWnd, L_UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { HANDLE_MSG (hWnd, WM_INITMENUPOPUP, Window_OnInitMenuPopup); HANDLE_MSG (hWnd, WM_LBUTTONDOWN, Window_OnLButtonDown); HANDLE_MSG (hWnd, WM_LBUTTONUP, Window_OnLButtonUp); HANDLE_MSG (hWnd, WM_MOUSEMOVE, Window_OnMouseMove); HANDLE_MSG (hWnd, WM_SETCURSOR, Window_OnSetCursor); HANDLE_MSG (hWnd, WM_PALETTECHANGED, Window_OnPaletteChanged); HANDLE_MSG (hWnd, WM_QUERYNEWPALETTE, Window_OnQueryNewPalette); HANDLE_MSG (hWnd, WM_ACTIVATE, Window_OnActivate); HANDLE_MSG (hWnd, WM_PALETTEISCHANGING, Window_OnPaletteChanging); HANDLE_MSG (hWnd, WM_SYSCOLORCHANGE, Window_SysColorChange); HANDLE_MSG (hWnd, WM_PAINT, Window_OnPaint); HANDLE_MSG (hWnd, WM_COMMAND, Window_OnCommand); HANDLE_MSG (hWnd, WM_DESTROY, Window_OnDestroy); HANDLE_MSG (hWnd, WM_TIMER, Window_OnTimer); HANDLE_MSG (hWnd, WM_SETFOCUS, Window_OnSetFocus); HANDLE_MSG (hWnd, WM_KILLFOCUS, Window_OnKillFocus); HANDLE_MSG (hWnd, WM_SIZE, Window_OnSize); HANDLE_MSG (hWnd, WM_HSCROLL, Window_OnHScroll); HANDLE_MSG (hWnd, WM_VSCROLL, Window_OnVScroll); } return DefWindowProc (hWnd, Message, wParam, lParam); } /*---[Window_OnInitMenuPopup]---------------------------------------------- Syntax: VOID Window_OnInitMenuPopup( HWND hWnd, HMENU hMenu, L_INT item, BOOL fSystemMenu ); Parameters: hWnd Window handle. hMenu The menu selected. item The ID of the item selected. fSystemMenu Is the menu the system menu? Prototype: Draw.h Notes: This procedure is responsible for handling WM_INITMENUPOPUP. --------------------------------------------------------------------------*/ VOID Window_OnInitMenuPopup (HWND hWnd, HMENU hMenu, L_INT item, BOOL fSystemMenu) { if (!fSystemMenu && GetSubMenu (GetMenu (hWnd), item) == hMenu) switch (item) { case MENU_FILE_POS: ENABLEMENUITEM (hMenu, IDM_SAVE, Data.Bitmap.Flags.Allocated); break; case MENU_DRAW_POS: ENABLEMENUITEM (hMenu, IDM_POINT, Data.Bitmap.Flags.Allocated); ENABLEMENUITEM (hMenu, IDM_LINE, Data.Bitmap.Flags.Allocated); ENABLEMENUITEM (hMenu, IDM_RECTANGLE, Data.Bitmap.Flags.Allocated); ENABLEMENUITEM (hMenu, IDM_ELLIPSE, Data.Bitmap.Flags.Allocated); ENABLEMENUITEM (hMenu, IDM_TEXT, Data.Bitmap.Flags.Allocated); ENABLEMENUPOS (hMenu, MENU_DRAW_MOVEREGION, Data.Bitmap.Flags.Allocated); ENABLEMENUPOS (hMenu, MENU_DRAW_REGION, bmoveregion); CHECKMENUITEM (hMenu, IDM_POINT, bpoint); CHECKMENUITEM (hMenu, IDM_LINE, bline); CHECKMENUITEM (hMenu, IDM_RECTANGLE, brectangle); CHECKMENUITEM (hMenu, IDM_ELLIPSE, bellipse); CHECKMENUITEM (hMenu, IDM_TEXT, btext); CHECKMENUPOS (hMenu, MENU_DRAW_MOVEREGION, bmarkregion || bmoveregion); CHECKMENUITEM (hMenu, IDM_TOOLRECT, bmoveregion && nRegionTool == IDM_TOOLRECT); CHECKMENUITEM (hMenu, IDM_TOOLELLIPSE, bmoveregion && nRegionTool == IDM_TOOLELLIPSE); CHECKMENUITEM (hMenu, IDM_TOOLRNDRECT, bmoveregion && nRegionTool == IDM_TOOLRNDRECT); CHECKMENUITEM (hMenu, IDM_TOOLFREEHAND, bmoveregion && nRegionTool == IDM_TOOLFREEHAND); break; case MENU_MODE_POS: CHECKMENUITEM (hMenu, IDM_SOLID, nLinestyle == PS_SOLID); CHECKMENUITEM (hMenu, IDM_DASH, nLinestyle == PS_DASH); CHECKMENUITEM (hMenu, IDM_DOT, nLinestyle == PS_DOT); CHECKMENUITEM (hMenu, IDM_SIZE1, nLinesize == 1); CHECKMENUITEM (hMenu, IDM_SIZE2, nLinesize == 2); CHECKMENUITEM (hMenu, IDM_SIZE3, nLinesize == 3); CHECKMENUITEM (hMenu, IDM_SIZE4, nLinesize == 4); CHECKMENUITEM (hMenu, IDM_SIZE5, nLinesize == 5); CHECKMENUITEM (hMenu, IDM_SIZE6, nLinesize == 6); CHECKMENUITEM (hMenu, IDM_SIZE7, nLinesize == 7); CHECKMENUITEM (hMenu, IDM_SIZE8, nLinesize == 8); CHECKMENUITEM (hMenu, IDM_SIZE9, nLinesize == 9); CHECKMENUITEM (hMenu, IDM_BLACK, nLinecolor == 0); CHECKMENUITEM (hMenu, IDM_WHITE, nLinecolor == 1); CHECKMENUITEM (hMenu, IDM_RED, nLinecolor == 2); CHECKMENUITEM (hMenu, IDM_GREEN, nLinecolor == 3); CHECKMENUITEM (hMenu, IDM_BLUE, nLinecolor == 4); } return; } /*---[Window_OnLButtonDown]---------------------------------------------- Syntax: VOID Window_OnLButtonDown( HWND hWnd, BOOL fDoubleClick, L_INT x, L_INT y, UINT keyFlags ); Parameters: hWnd Window handle. fDoubleClick Was the button double-clicked? x X position of the mouse. y Y position of the mouse. keyFlags Which keys were also pressed. Prototype: Draw.h Notes: This procedure is responsible for handling WM_LBUTTONDOWN. --------------------------------------------------------------------------*/ VOID Window_OnLButtonDown (HWND hWnd, BOOL fDoubleClick, L_INT x, L_INT y, UINT keyFlags) { HDC hdc; UNREFERENCED_PARAMETER (keyFlags); UNREFERENCED_PARAMETER (fDoubleClick); /* note: the mouse position is in view coordinates */ /* bitmap coordinates: xbitmap = xclient + Data.rcView.left ybitmap = yclient + Data.rcView.top */ x -= Data.rcView.left; y -= Data.rcView.top; if (!bDraw) { if (bmoveregion) { hdc = GetDC (hWnd); /* nRow means y and nCol means x!! */ if (!L_IsPtInBitmapRgn (&Data.Bitmap, y, x)) { xAnchor = yAnchor = -1; xold = yold = -1; bmoveregion = FALSE; bmarkregion = TRUE; ReleaseDC (hWnd, hdc); ReleaseCapture (); FreeBitmaps(); L_FreeBitmapRgn(&Data.Bitmap); KillTimer(hWnd, ID_REGIONEVENT); InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); return; } /* stop displaying the frame while dragging the region */ KillTimer(hWnd, ID_REGIONEVENT); /* disable the region within the original bitmap */ L_FreeBitmapRgn(&Data.Bitmap); /* restore the background */ L_CombineBitmap( &Data.Bitmap, xMoveSrc, yMoveSrc, nMoveWidth, nMoveHeight, &bmSave, 0, 0, L_SRCCOPY ); } else { if( bmarkregion ) { if( pptRegion ) GlobalFreePtr(pptRegion); if(nRegionTool == IDM_TOOLFREEHAND) pptRegion = (LPPOINT) GlobalAllocPtr(GHND, (L_UINT32) sizeof(POINT) * MAXPOINTS); else pptRegion = (LPPOINT) GlobalAllocPtr(GHND, (L_UINT32) sizeof(POINT) * 2); if(pptRegion) { nNextPt = 0; pptRegion[nNextPt].x = x; pptRegion[nNextPt].y = y; nNextPt++; } } SetCapture (hWnd); } xAnchor = x; yAnchor = y; bDraw = TRUE; } return; } /*---[Window_OnLButtonUp]------------------------------------------------- Syntax: VOID Window_OnLButtonUp(HWND hWnd, L_INT x, L_INT y, UINT keyFlags); Parameters: hWnd Window handle. x X position of the mouse. y Y position of the mouse. keyFlags Which keys were also pressed. Prototype: Draw.h Notes: This procedure is responsible for handling WM_LBUTTONUP. --------------------------------------------------------------------------*/ VOID Window_OnLButtonUp (HWND hWnd, L_INT x, L_INT y, UINT keyFlags) { HDC hdcLead; HPEN hPen; HBRUSH hBrush; HFONT hFont; RECT rc; RGNXFORM XForm; L_INT nRet; HCURSOR hOldCursor; UNREFERENCED_PARAMETER (keyFlags); /* note: the mouse position is in view coordinates */ /* bitmap coordinates: xbitmap = xclient - Data.rcView.left ybitmap = yclient - Data.rcView.top */ x -= Data.rcView.left; y -= Data.rcView.top; if (bDraw) { if (bmarkregion && ((xold != -1) && (yold != -1) || nRegionTool == IDM_TOOLCOLOR)) { hOldCursor = SetCursor(LoadCursor(NULL,IDC_WAIT)); HiliteMark(hWnd, FALSE); if(nNextPt > 1 || nRegionTool == IDM_TOOLCOLOR) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = BITMAPWIDTH(&Data.Bitmap); XForm.nXScalarDen = RECTWIDTH(&Data.rcView); XForm.nYScalarNum = BITMAPHEIGHT(&Data.Bitmap); XForm.nYScalarDen = RECTHEIGHT(&Data.rcView); XForm.nXOffset = 0; XForm.nYOffset = 0; switch(nRegionTool) { case IDM_TOOLRECT: SetRect(&rc, min(pptRegion[0].x, pptRegion[1].x), min(pptRegion[0].y, pptRegion[1].y), max(pptRegion[0].x, pptRegion[1].x), max(pptRegion[0].y, pptRegion[1].y)); nRet = L_SetBitmapRgnRect(&Data.Bitmap, &XForm, &rc, L_RGN_SET); break; case IDM_TOOLRNDRECT: SetRect(&rc, min(pptRegion[0].x, pptRegion[1].x), min(pptRegion[0].y, pptRegion[1].y), max(pptRegion[0].x, pptRegion[1].x), max(pptRegion[0].y, pptRegion[1].y)); nRet = L_SetBitmapRgnRoundRect(&Data.Bitmap, &XForm, &rc, abs(pptRegion[0].x - pptRegion[1].x) / 4, abs(pptRegion[0].y - pptRegion[1].y) / 4, L_RGN_SET); break; case IDM_TOOLELLIPSE: SetRect(&rc, min(pptRegion[0].x, pptRegion[1].x), min(pptRegion[0].y, pptRegion[1].y), max(pptRegion[0].x, pptRegion[1].x), max(pptRegion[0].y, pptRegion[1].y)); nRet = L_SetBitmapRgnEllipse(&Data.Bitmap, &XForm, &rc, L_RGN_SET); break; case IDM_TOOLFREEHAND: nRet = L_SetBitmapRgnPolygon(&Data.Bitmap, &XForm, pptRegion, nNextPt, L_POLY_WINDING, L_RGN_SET); L_GetBitmapRgnBounds( &Data.Bitmap, &XForm, &rc ); break; case IDM_TOOLCOLOR: /* note: this is a slow function since it has to go through every pixel in the bitmap to find a matching color! */ nRet = L_SetBitmapRgnColor(&Data.Bitmap, L_GetPixelColor(&Data.Bitmap, y, x), L_RGN_SET); L_GetBitmapRgnBounds( &Data.Bitmap, &XForm, &rc ); break; } if(nRet = SUCCESS) { bmoveregion = TRUE; SetTimer(hWnd, ID_REGIONEVENT, REGIONEVENTDELAY, NULL); } } ReleaseCapture (); /* outline the region without waiting for the WM_TIMER message */ OutlineBitmapRgn(hWnd, NULL); /* free the array holding the points */ GlobalFreePtr(pptRegion); pptRegion = NULL; xMoveSrc = xMoveDest = rc.left; yMoveSrc = yMoveDest = rc.top; nMoveWidth = RECTWIDTH(&rc); nMoveHeight = RECTHEIGHT(&rc); bmoveregion = TRUE; bmarkregion = FALSE; bDraw = FALSE; ReleaseCapture (); CreateRegionBitmaps(hWnd); SetTimer(hWnd, ID_REGIONEVENT, REGIONEVENTDELAY, NULL); SetCursor(hOldCursor); return; } else if (bmoveregion) { hOldCursor = SetCursor(LoadCursor(NULL,IDC_WAIT)); /* save the background */ L_CombineBitmap( &bmSave, 0, 0, nMoveWidth, nMoveHeight, &Data.Bitmap, xMoveDest, yMoveDest, L_SRCCOPY ); /* set up the transform structure */ XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = XForm.nXScalarDen = XForm.nYScalarNum = XForm.nYScalarDen = 1; XForm.nXOffset = xMoveDest; XForm.nYOffset = yMoveDest; /* set the region in the original bitmap */ L_SetBitmapRgnHandle( &Data.Bitmap, &XForm, hrgnRegion, L_RGN_SET ); /* copy the floater bitmap to the new position */ L_CombineBitmap( &Data.Bitmap, xMoveDest, yMoveDest, nMoveWidth, nMoveHeight, &bmFloater, 0, 0, L_SRCCOPY ); /* and we can still move */ xMoveSrc = xMoveDest; yMoveSrc = yMoveDest; xAnchor = yAnchor = -1; xold = yold = -1; InvalidateRect (hWnd, NULL, FALSE); SetTimer(hWnd, ID_REGIONEVENT, REGIONEVENTDELAY, NULL); UpdateWindow (hWnd); /* outline the region without waiting for the WM_TIMER message */ OutlineBitmapRgn(hWnd, NULL); SetCursor(hOldCursor); } else if (bpoint) { hdcLead = L_CreateLeadDC (&Data.Bitmap); SetPixel (hdcLead, xAnchor, yAnchor, Color (nLinecolor)); SetRect (&rc, 0, 0, 1, 1); OffsetRect (&rc, xAnchor, yAnchor); L_DeleteLeadDC (hdcLead); xAnchor = yAnchor = -1; xold = yold = -1; /* translate the rectangle to client coordinates */ OffsetRect( &rc, Data.rcView.left, Data.rcView.top ); InvalidateRect (hWnd, &rc, FALSE); UpdateWindow (hWnd); } else if (bline) { hdcLead = L_CreateLeadDC (&Data.Bitmap); SetBkMode (hdcLead, TRANSPARENT); hPen = CreatePen ((nLinesize > 1) ? 0 : nLinestyle, nLinesize, Color (nLinecolor)); hPen = SelectObject (hdcLead, hPen); MoveTo (hdcLead, xAnchor, yAnchor); LineTo (hdcLead, x, y); SetRect (&rc, min (xAnchor, x), min (yAnchor, y), max (xAnchor, x), max (yAnchor, y)); InflateRect (&rc, (nLinesize + 1) / 2, (nLinesize + 1) / 2); DeleteObject (SelectObject (hdcLead, hPen)); L_DeleteLeadDC (hdcLead); xAnchor = yAnchor = -1; xold = yold = -1; /* translate the rectangle to client coordinates */ OffsetRect( &rc, Data.rcView.left, Data.rcView.top ); InvalidateRect (hWnd, &rc, FALSE); UpdateWindow (hWnd); } else if (brectangle) { hdcLead = L_CreateLeadDC (&Data.Bitmap); SetBkMode (hdcLead, TRANSPARENT); hBrush = SelectObject (hdcLead, GetStockObject (NULL_BRUSH)); hPen = CreatePen ((nLinesize > 1) ? 0 : nLinestyle, nLinesize, Color (nLinecolor)); hPen = SelectObject (hdcLead, hPen); Rectangle (hdcLead, xAnchor, yAnchor, x, y); SetRect (&rc, min (xAnchor, x), min (yAnchor, y), max (xAnchor, x), max (yAnchor, y)); InflateRect (&rc, (nLinesize + 1) / 2, (nLinesize + 1) / 2); DeleteObject (SelectObject (hdcLead, hPen)); SelectObject (hdcLead, hBrush); L_DeleteLeadDC (hdcLead); xAnchor = yAnchor = -1; xold = yold = -1; /* translate the rectangle to client coordinates */ OffsetRect( &rc, Data.rcView.left, Data.rcView.top ); InvalidateRect (hWnd, &rc, FALSE); UpdateWindow (hWnd); } else if (bellipse) { hdcLead = L_CreateLeadDC (&Data.Bitmap); SetBkMode (hdcLead, TRANSPARENT); hBrush = SelectObject (hdcLead, GetStockObject (NULL_BRUSH)); hPen = CreatePen ((nLinesize > 1) ? 0 : nLinestyle, nLinesize, Color (nLinecolor)); hPen = SelectObject (hdcLead, hPen); Ellipse (hdcLead, xAnchor, yAnchor, x, y); SetRect (&rc, min (xAnchor, x), min (yAnchor, y), max (xAnchor, x), max (yAnchor, y)); InflateRect (&rc, (nLinesize + 1) / 2, (nLinesize + 1) / 2); DeleteObject (SelectObject (hdcLead, hPen)); SelectObject (hdcLead, hBrush); L_DeleteLeadDC (hdcLead); xAnchor = yAnchor = -1; xold = yold = -1; /* translate the rectangle to client coordinates */ OffsetRect( &rc, Data.rcView.left, Data.rcView.top ); InvalidateRect (hWnd, &rc, FALSE); UpdateWindow (hWnd); } else if (btext) { hdcLead = L_CreateLeadDC (&Data.Bitmap); SetBkMode (hdcLead, TRANSPARENT); SetTextColor (hdcLead, Color (nLinecolor)); hFont = SelectObject (hdcLead, GetStockObject (ANSI_VAR_FONT)); TextOut (hdcLead, xAnchor, yAnchor, szText, lstrlen (szText)); SelectObject (hdcLead, hFont); L_DeleteLeadDC (hdcLead); xAnchor = yAnchor = -1; xold = yold = -1; /* translate the rectangle to client coordinates */ OffsetRect( &rc, Data.rcView.left, Data.rcView.top ); InvalidateRect (hWnd, NULL, FALSE); UpdateWindow (hWnd); } bDraw = FALSE; ReleaseCapture (); } return; } /*---[Window_OnMouseMove]------------------------------------------------- Syntax: VOID Window_OnMouseMove( HWND hWnd, L_INT x, L_INT y, UINT keyFlags ); Parameters: hWnd Window handle. x X position of the mouse. y Y position of the mouse. keyFlags Which keys were also pressed. Prototype: Draw.h Notes: This procedure is responsible for handling WM_MOUSEMOVE. --------------------------------------------------------------------------*/ VOID Window_OnMouseMove (HWND hWnd, L_INT x, L_INT y, UINT keyFlags) { HDC hdc; HDC hdcUnion; HDC hdcRegion; HPEN hPen; HBRUSH hBrush; HBITMAP hbmUnion = 0, holdUnion, holdRegion; RECT rcSave; RECT rcUnion; RECT rcRegion; L_INT nUnionWidth = 0; L_INT nUnionHeight = 0; L_INT nDrawMode; UNREFERENCED_PARAMETER (keyFlags); x -= Data.rcView.left; y -= Data.rcView.top; if (bDraw) { if (bmoveregion) { hdc = GetDC (hWnd); /* All the x values are relative to the bitmap set the viewport of the DC to match the bitmap */ SetViewportOrgEx( hdc, Data.rcView.left, Data.rcView.top, NULL ); IntersectClipRect (hdc, 0, 0, BITMAPWIDTH(&Data.Bitmap), BITMAPHEIGHT(&Data.Bitmap)); SetRect (&rcSave, 0, 0, nMoveWidth, nMoveHeight); rcRegion = rcSave; OffsetRect (&rcSave, xMoveDest, yMoveDest); xMoveDest = xMoveDest + x - xAnchor; yMoveDest = yMoveDest + y - yAnchor; xAnchor = x; yAnchor = y; OffsetRect (&rcRegion, xMoveDest, yMoveDest); if (IntersectRect (&rcUnion, &rcSave, &rcRegion)) { UnionRect (&rcUnion, &rcSave, &rcRegion); /* create a DDB from the origial bitmap the size of the union */ nUnionWidth = rcUnion.right - rcUnion.left; nUnionHeight = rcUnion.bottom - rcUnion.top; hbmUnion = CreateCompatibleBitmap(hdc, nUnionWidth, nUnionHeight ); OffsetRect (&rcRegion, -rcUnion.left, -rcUnion.top); OffsetRect (&rcSave, -rcUnion.left, -rcUnion.top); hdcUnion = CreateCompatibleDC (hdc); holdUnion = SelectObject (hdcUnion, hbmUnion); hdcRegion = CreateCompatibleDC (hdc); holdRegion = SelectObject (hdcRegion, hbmSave); /* copy to the union DDB what's on the screen */ BitBlt( hdcUnion, 0, 0, nUnionWidth, nUnionHeight, hdc, rcUnion.left, rcUnion.top, SRCCOPY ); /* restore the background into the union. Now the union bitmap should contain what should on the screen without the floating bitmap */ BitBlt( hdcUnion, rcSave.left, rcSave.top, nMoveWidth, nMoveHeight, hdcRegion, 0, 0, SRCCOPY ); /* get the new background into hbmSave */ BitBlt (hdcRegion, 0, 0, nMoveWidth, nMoveHeight, hdcUnion, rcRegion.left, rcRegion.top, SRCCOPY); /* Paint only what's is inside the region using Windows's ability to do clipping. Select the region into the union DC */ SelectObject( hdcUnion, hrgnRegion ); OffsetClipRgn( hdcUnion, rcRegion.left, rcRegion.top ); /* select the floater DDB */ SelectObject( hdcRegion, hbmFloater ); /* Now the union DDB is what should be on the screen */ BitBlt (hdcUnion, rcRegion.left, rcRegion.top, nMoveWidth, nMoveHeight, hdcRegion, 0, 0, SRCCOPY); /* blast the whole thing to the screen */ BitBlt( hdc, rcUnion.left, rcUnion.top, nUnionWidth, nUnionHeight, hdcUnion, 0, 0, SRCCOPY ); SelectObject( hdcUnion, holdUnion ); DeleteDC(hdcUnion); SelectObject( hdcRegion, holdRegion ); DeleteDC(hdcRegion); DeleteObject( hbmUnion ); } else { hdcRegion = CreateCompatibleDC (hdc); holdRegion = SelectObject (hdcRegion, hbmSave); /* restore the background */ BitBlt( hdc, rcSave.left, rcSave.top, nMoveWidth, nMoveHeight, hdcRegion, 0, 0, SRCCOPY ); /* save the background */ BitBlt (hdcRegion, 0, 0, nMoveWidth, nMoveHeight, hdc, xMoveDest, yMoveDest, SRCCOPY); /* Paint only what's is inside the region using Windows's ability to do clipping. Select the floater into the union DC */ SelectObject( hdc, hrgnRegion ); OffsetClipRgn( hdc, xMoveDest, yMoveDest ); /* paint only what's INSIDE the region */ SelectObject( hdcRegion, hbmFloater ); BitBlt (hdc, xMoveDest, yMoveDest, nMoveWidth, nMoveHeight, hdcRegion, 0, 0, SRCCOPY); SelectObject( hdcRegion, holdRegion ); DeleteDC(hdcRegion); } ReleaseDC (hWnd, hdc); } else if (bmarkregion) { switch(nRegionTool) { case IDM_TOOLFREEHAND: if(nNextPt < MAXPOINTS) { pptRegion[nNextPt].x = x; pptRegion[nNextPt].y = y; nNextPt++; } break; default: HiliteMark(hWnd, FALSE); pptRegion[1].x = x; pptRegion[1].y = y; nNextPt = 2; break; } HiliteMark(hWnd, TRUE); if (xold == -1) { xold = xAnchor; yold = yAnchor; } } else if (bline) { hdc = GetDC (hWnd); IntersectClipRect (hdc, 0, 0, BITMAPWIDTH(&Data.Bitmap), BITMAPHEIGHT(&Data.Bitmap)); SetBkMode (hdc, TRANSPARENT); hPen = CreatePen ((nLinesize > 1) ? 0 : nLinestyle, nLinesize, Color (nLinecolor)); hPen = SelectObject (hdc, hPen); nDrawMode = GetROP2 (hdc); SetROP2 (hdc, R2_NOT); MoveTo (hdc, xAnchor + Data.rcView.left, yAnchor + Data.rcView.top); if (xold == -1) { xold = xAnchor; yold = yAnchor; } LineTo (hdc, xold + Data.rcView.left, yold + Data.rcView.top); MoveTo (hdc, xAnchor + Data.rcView.left, yAnchor + Data.rcView.top); point.x = x; point.y = y; LineTo (hdc, point.x + Data.rcView.left, point.y + Data.rcView.top); xold = point.x; yold = point.y; DeleteObject (SelectObject (hdc, hPen)); SetROP2 (hdc, nDrawMode); ReleaseDC (hWnd, hdc); } else if (brectangle) { hdc = GetDC (hWnd); IntersectClipRect (hdc, 0, 0, BITMAPWIDTH(&Data.Bitmap), BITMAPHEIGHT(&Data.Bitmap)); SetBkMode (hdc, TRANSPARENT); hPen = CreatePen ((nLinesize > 1) ? 0 : nLinestyle, nLinesize, Color (nLinecolor)); hPen = SelectObject (hdc, hPen); nDrawMode = GetROP2 (hdc); SetROP2 (hdc, R2_NOT); if (xold == -1) { xold = xAnchor; yold = yAnchor; } hBrush = SelectObject (hdc, GetStockObject (NULL_BRUSH)); Rectangle (hdc, xAnchor + Data.rcView.left, yAnchor + Data.rcView.top, xold + Data.rcView.left, yold + Data.rcView.top); point.x = x; point.y = y; Rectangle (hdc, xAnchor + Data.rcView.left, yAnchor + Data.rcView.top, point.x + Data.rcView.left, point.y + Data.rcView.top); DeleteObject (SelectObject (hdc, hPen)); SelectObject (hdc, hBrush); xold = point.x; yold = point.y; SetROP2 (hdc, nDrawMode); ReleaseDC (hWnd, hdc); } else if (bellipse) { hdc = GetDC (hWnd); IntersectClipRect (hdc, 0, 0, BITMAPWIDTH(&Data.Bitmap), BITMAPHEIGHT(&Data.Bitmap)); SetBkMode (hdc, TRANSPARENT); hPen = CreatePen ((nLinesize > 1) ? 0 : nLinestyle, nLinesize, Color (nLinecolor)); hPen = SelectObject (hdc, hPen); nDrawMode = GetROP2 (hdc); SetROP2 (hdc, R2_NOT); if (xold == -1) { xold = xAnchor; yold = yAnchor; } hBrush = SelectObject (hdc, GetStockObject (NULL_BRUSH)); Ellipse (hdc, xAnchor + Data.rcView.left, yAnchor + Data.rcView.top, xold + Data.rcView.left, yold + Data.rcView.top); point.x = x; point.y = y; Ellipse (hdc, xAnchor + Data.rcView.left, yAnchor + Data.rcView.top, point.x + Data.rcView.left, point.y + Data.rcView.top); DeleteObject (SelectObject (hdc, hPen)); SelectObject (hdc, hBrush); xold = point.x; yold = point.y; SetROP2 (hdc, nDrawMode); ReleaseDC (hWnd, hdc); } } return; } /*---[Window_OnMouseMove]------------------------------------------------- Syntax: VOID Window_OnMouseMove( HWND hWnd, L_INT x, L_INT y, UINT keyFlags ); Parameters: hWnd Window handle. x X position of the mouse. y Y position of the mouse. keyFlags Which keys were also pressed. Prototype: Draw.h Notes: This procedure is responsible for handling WM_MOUSEMOVE. --------------------------------------------------------------------------*/ BOOL Window_OnSetCursor(HWND hWnd, HWND wParam, UINT nHittest, UINT wMouseMsg) { POINT pt; GetCursorPos(&pt); ScreenToClient(hWnd,&pt); if( L_BitmapHasRgn(&Data.Bitmap) && bmoveregion && L_IsPtInBitmapRgn(&Data.Bitmap, pt.y - Data.rcView.top, pt.x - Data.rcView.left) ) SetCursor(hcrHand); else if( nRegionTool == IDM_TOOLCOLOR && bmarkregion && pt.x >= 0 && pt.y >= 0 && pt.x < Data.rcView.right && pt.y < Data.rcView.bottom ) SetCursor(hcrEyeDrop); else DefWindowProc(hWnd, WM_SETCURSOR, (WPARAM)wParam, MAKELONG(nHittest,wMouseMsg)); return TRUE; } /*---[FreeBitmaps]----------------------------------------------------- Syntax: VOID FreeBitmaps () Parameters: NONE. Prototype: Draw.h Notes: This procedure frees all the bitmaps associated with moving a floater. --------------------------------------------------------------------------*/ VOID FreeBitmaps () { if( bmSave.Flags.Allocated ) L_FreeBitmap( &bmSave ); if( bmFloater.Flags.Allocated ) L_FreeBitmap( &bmFloater ); if( hbmFloater ) { DeleteObject( hbmFloater ); hbmFloater = NULL; } if( hbmSave ) { DeleteObject( hbmSave ); hbmSave = NULL; } if( pptRegion ) { GlobalFreePtr( pptRegion ); pptRegion = NULL; } if( hrgnRegion ) { DeleteObject( hrgnRegion ); hrgnRegion = NULL; } } /*---[Window_OnCommand]----------------------------------------------------- Syntax: VOID Window_OnCommand( HWND hWnd, L_INT id, HWND hwndCtl, UINT codeNotify ) Parameters: hWnd Window handle. id Menu item or Control ID. hwndCtl 0 if menu item selected, else window handle of the control. codeNotify 1 if accelerator keystroke, else notification code, such as BN_CLICKED. Prototype: Draw.h Notes: This procedure is responsible for handling WM_ONCOMMAND. --------------------------------------------------------------------------*/ VOID Window_OnCommand (HWND hWnd, L_INT id, HWND hwndCtl, UINT codeNotify) { FARPROC lpfnDialogProc; L_TCHAR szFileName[MAXFILENAME]; UNREFERENCED_PARAMETER (hwndCtl); UNREFERENCED_PARAMETER (codeNotify); switch (id) { case IDM_EXIT: DestroyWindow (hWnd); break; case IDM_OPEN: if (GetOpenBitmapFile (hWnd, (LPTSTR) szFileName)) { if (ImageLoad (hWnd, (LPTSTR) szFileName)) { break; } } FORWARD_WM_QUERYNEWPALETTE (hWnd, SendMessage); InvalidateRect (hWnd, NULL, TRUE); break; case IDM_POINT: Reset_Draw (hWnd); bpoint = TRUE; break; case IDM_LINE: Reset_Draw (hWnd); bline = TRUE; break; case IDM_RECTANGLE: Reset_Draw (hWnd); brectangle = TRUE; break; case IDM_ELLIPSE: Reset_Draw (hWnd); bellipse = TRUE; break; case IDM_TEXT: Reset_Draw (hWnd); lpfnDialogProc = MakeProcInstance ((FARPROC) TextDialogProc, hInstApp); DialogBox (hInstApp, TEXT("idd_dialog1"), hWnd, (DLGPROC) lpfnDialogProc); FreeProcInstance (lpfnDialogProc); btext = TRUE; break; case IDM_TOOLRECT: case IDM_TOOLELLIPSE: case IDM_TOOLRNDRECT: case IDM_TOOLFREEHAND: case IDM_TOOLCOLOR: Reset_Draw (hWnd); bmarkregion = TRUE; nRegionTool = id; /* the move floater operations become complicated if the bitmap's view perspective is BOTTOM_LEFT */ if( Data.Bitmap.ViewPerspective == BOTTOM_LEFT ) { L_FlipBitmap( &Data.Bitmap ); Data.Bitmap.ViewPerspective = TOP_LEFT; } break; case IDM_ROTATEREGION: case IDM_FLIPREGION: case IDM_REVERSEREGION: case IDM_RESIZEREGION: //case IDM_RESAMPLEREGION: case IDM_BRIGHTNESSREGION: case IDM_CONTRASTREGION: ChangeRegion(hWnd, id); break; case IDM_SIZE1: case IDM_SIZE2: case IDM_SIZE3: case IDM_SIZE4: case IDM_SIZE5: case IDM_SIZE6: case IDM_SIZE7: case IDM_SIZE8: case IDM_SIZE9: nLinesize = id - IDM_SIZE1 + 1; break; case IDM_SOLID: case IDM_DASH: case IDM_DOT: nLinestyle = id - IDM_SOLID; break; case IDM_BLACK: case IDM_WHITE: case IDM_RED: case IDM_GREEN: case IDM_BLUE: nLinecolor = id - IDM_BLACK; break; case IDM_NORMAL: nLinesize = 1; nLinestyle = 0; nLinecolor = 1; break; case IDM_SAVE: SaveBitmapFile (hWnd, &Data.Bitmap); break; } return; } /*----(Window_OnPaletteChanged)-------------------------------------------- Syntax: VOID Window_OnPaletteChanged( HWND hWnd, HWND hWndPaletteChange ) Parameters: hwnd Handle to a window. hWndPaletteChange Handle to a window that has the palette realized. Prototype: Draw.h Notes: This procedure is responsible for handling WM_PALETTECHANGED. --------------------------------------------------------------------------*/ VOID Window_OnPaletteChanged (HWND hWnd, HWND hWndPaletteChange) { HDC hDC; HPALETTE hPalette; /* If this window initiated the palette change, do nothing. */ if (hWnd == hWndPaletteChange) return; /* Delete the previous palette, if there is one. */ if (Data.hPalette) { DeleteObject (Data.hPalette); Data.hPalette = NULL; } /* Does this window have a bitmap and a palette? */ if (Data.Bitmap.Flags.Allocated) { hDC = GetDC (hWnd); /* Generate a new logical palette (if needed) for painting. */ Data.hPalette = L_CreatePaintPalette (hDC, &Data.Bitmap); /* Select and Realize the palette. */ hPalette = SelectPalette (hDC, Data.hPalette, TRUE); RealizePalette (hDC); /* Force a repaint. */ InvalidateRect (hWnd, NULL, FALSE); /* Return the old palette. */ SelectPalette (hDC, hPalette, TRUE); ReleaseDC (hWnd, hDC); } return; } /*----(Window_OnQueryNewPalette)-------------------------------------------- Syntax: BOOL Window_OnQueryNewPalette( HWND hWnd ) Parameters: hWnd Handle to a window. Prototype: Draw.h Notes: This procedure is responsible for handling WM_QUERYNEWPALETTE. --------------------------------------------------------------------------*/ BOOL Window_OnQueryNewPalette (HWND hWnd) { HDC hDC; HPALETTE hPalette; L_INT nNoColors = 0; /* Delete the previous palette, if there is one. */ if (Data.hPalette) { DeleteObject (Data.hPalette); Data.hPalette = NULL; } if (Data.Bitmap.Flags.Allocated) { hDC = GetDC (hWnd); /* Generate a new logical palette (if needed) for painting. */ Data.hPalette = L_CreatePaintPalette (hDC, &Data.Bitmap); if (Data.hPalette) /* Is a palette needed? */ { hPalette = SelectPalette (hDC, Data.hPalette, FALSE); nNoColors = RealizePalette (hDC); if (nNoColors) /* If the palette changed, force a WM_PAINT */ InvalidateRect (hWnd, NULL, FALSE); /* Restore the old palette. */ SelectPalette (hDC, hPalette, TRUE); } ReleaseDC (hWnd, hDC); } return (nNoColors); } /*---[Window_OnActivate]----------------------------------------------------- Syntax: VOID Window_OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized) Parameters: hWnd Window handle. state WA_ACTIVE | WA_CLICKACTIVE | WA_INACTIVE hwndActDeact the winodw habdle that deactivate fMinimized Window is minimized Prototype: Color.h Notes: This procedure is responsible for handling WM_ACTIVATE. --------------------------------------------------------------------------*/ VOID Window_OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized) { if(state!=WA_INACTIVE) Window_OnQueryNewPalette (hwnd); } /*====(Window_OnPaletteChanging)========================================== Description: Enumerates all child windows and asks them to realize their logical palettes beside the physical palette. Syntax : VOID Window_OnPaletteChanging(HWND hwnd, HWND hWndPaletteChange) Parameters : hwnd Handle to a window. hWndPaletteChange Handle to a window that has the palette realized. Return Value: None. ==========================================================================*/ VOID Window_OnPaletteChanging(HWND hWnd, HWND hWndPaletteChange) { Window_OnPaletteChanged (hWnd, hWndPaletteChange); } /*====(Window_SysColorChange)========================================== Syntax: VOID Window_SysColorChange( HWND hWnd ) Parameters: hWnd Handle to a window. Prototype: Loadsave.h Notes: This procedure is responsible for handling WM_SYSCOLORCHANGE. --------------------------------------------------------------------------*/ VOID Window_SysColorChange(HWND hwnd) { Window_OnQueryNewPalette (hwnd); } /*---[Window_OnPaint]------------------------------------------------------- Syntax: VOID Window_OnPaint( HWND hWnd ); Parameters: hWnd Window handle. Prototype: Draw.h Notes: This procedure is responsible for handling WM_PAINT. --------------------------------------------------------------------------*/ VOID Window_OnPaint (HWND hWnd) { HDC hdc; RECT rc; PAINTSTRUCT ps; HPALETTE hOldPal = NULL; hdc = BeginPaint (hWnd, &ps);/* Get DC */ if (Data.Bitmap.Flags.Allocated) /* Do we have an image? */ { if (Data.hPalette) hOldPal = SelectPalette (ps.hdc, Data.hPalette, TRUE); /* Setup the Destination Rectangle. */ SetRect (&rc, 0, 0, BITMAPWIDTH(&Data.Bitmap), BITMAPHEIGHT(&Data.Bitmap)); /* Paint it */ L_PaintDC (hdc, &Data.Bitmap, NULL, NULL, &Data.rcView, &ps.rcPaint, SRCCOPY); if (Data.hPalette) SelectPalette (ps.hdc, hOldPal, TRUE); } EndPaint (hWnd, &ps); /* Return DC */ return; } /*---[Window_OnDestroy]---------------------------------------------------- Syntax: VOID Window_OnDestroy( HWND hWnd ); Parameters: hWnd Window handle. Prototype: Draw.h Notes: This procedure is responsible for handling WM_DESTROY. --------------------------------------------------------------------------*/ VOID Window_OnDestroy (HWND hWnd) { UNREFERENCED_PARAMETER (hWnd); if (Data.Bitmap.Flags.Allocated) /* Do we have an image? */ L_FreeBitmap (&Data.Bitmap); if (Data.hPalette) /* Delete palette if there is one. */ DeleteObject (Data.hPalette); /* free the bitmaps associated with moving regions */ FreeBitmaps(); PostQuitMessage (0); return; } /*---[Window_OnSetFocus]---------------------------------------------------- Syntax: VOID Window_OnSetFocus(HWND hwnd, HWND hwndOldFocus) Parameters: hwnd Window handle. hwndOldFocus The window that lost the focus Prototype: Draw.h Notes: This procedure is responsible for handling WM_SETFOCUS. --------------------------------------------------------------------------*/ VOID Window_OnSetFocus(HWND hwnd, HWND hwndOldFocus) { if(bmoveregion) SetTimer(hwnd, ID_REGIONEVENT, REGIONEVENTDELAY, NULL); } /*---[Window_OnKillFocus]---------------------------------------------------- Syntax: VOID Window_OnSetFocus(HWND hwnd, HWND hwndNewFocus) Parameters: hwnd Window handle. hwndNewFocus The window that received the focus Prototype: Draw.h Notes: This procedure is responsible for handling WM_KILLFOCUS. --------------------------------------------------------------------------*/ VOID Window_OnKillFocus(HWND hwnd, HWND hwndNewFocus) { if(bmoveregion) KillTimer(hwnd, ID_REGIONEVENT); } /*---[Window_OnTimer]---------------------------------------------------- Syntax: VOID Window_OnTimer(HWND hWnd, UINT id) Parameters: hwnd Window handle. id The timer id. Prototype: Draw.h Notes: This procedure is responsible for handling WM_TIMER. It creates the illusion of the moving frame repainting the frame with a different brush. The 8 brushes have a diagonal pattern similar with the moving cilinder at the barber shop. --------------------------------------------------------------------------*/ L_VOID Window_OnTimer(HWND hWnd, UINT id) { switch(id) { case ID_REGIONEVENT: Data.uRegionMask = (Data.uRegionMask + 1) % 8; OutlineBitmapRgn(hWnd, NULL); break; } } /*----(Window_ProcessSize)--------------------------------------------------- Syntax : VOID Window_ProcessSize(HWND hWnd, UINT nState, L_INT nCx, L_INT nCy) Parameters : hWnd Handle to the child window. nState State of resizing requested. nCx Size to be used for the "x" direction. nCy Size to be used for the "y" direction. Return Value: None. Description: Responds to WM_SIZE message and sets the internal data accordingly. --------------------------------------------------------------------------*/ static VOID Window_ProcessSize (HWND hWnd, UINT nState, L_INT nCx, L_INT nCy) { static L_BOOL fSizeInUse = FALSE; L_INT nWidth, nHeight, nVScroll, nHScroll; DWORD dwStyle; if (!fSizeInUse) { fSizeInUse = TRUE; if (nState != SIZEICONIC) { nWidth = BITMAPWIDTH(&Data.Bitmap); nHeight = BITMAPHEIGHT(&Data.Bitmap); Data.cxClient = nCx; Data.cyClient = nCy; dwStyle = GetWindowLong (hWnd, GWL_STYLE); nVScroll = GetSystemMetrics (SM_CXVSCROLL) - GetSystemMetrics(SM_CXBORDER); nHScroll = GetSystemMetrics (SM_CYHSCROLL) - GetSystemMetrics(SM_CYBORDER); if (WS_VSCROLL & dwStyle) Data.cxClient += nVScroll; if (WS_HSCROLL & dwStyle) Data.cyClient += nHScroll; if (Data.cxClient < nWidth) { Data.cyClient -= nHScroll; if (Data.cyClient < nHeight) Data.cxClient -= nVScroll; } else if (Data.cyClient < nHeight) { Data.cxClient -= nVScroll; if (Data.cxClient < nWidth) Data.cyClient -= nHScroll; } Data.nHScrollStep = max (1, (Data.cxClient / SCROLL_RATIO)); Data.nVScrollStep = max (1, (Data.cyClient / SCROLL_RATIO)); Data.nVScrollMax = max (0, (nHeight - Data.cyClient /*- 1*/)); Data.nVScrollPos = max (0, min (Data.nVScrollPos, Data.nVScrollMax)); Data.nHScrollMax = max (0, (nWidth - Data.cxClient /*- 1*/)); Data.nHScrollPos = max (0, min (Data.nHScrollPos, Data.nHScrollMax)); SetRect (&Data.rcView, 0, 0, nWidth, nHeight); OffsetRect (&Data.rcView, -Data.nHScrollPos, -Data.nVScrollPos); SetScrollRange (hWnd, SB_HORZ, 0, Data.nHScrollMax, FALSE); SetScrollPos (hWnd, SB_HORZ, Data.nHScrollPos, TRUE); SetScrollRange (hWnd, SB_VERT, 0, Data.nVScrollMax, FALSE); SetScrollPos (hWnd, SB_VERT, Data.nVScrollPos, TRUE); } fSizeInUse = FALSE; } return; } /*----(Window_OnSize)------------------------------------------------------- Syntax : VOID Window_OnSize(HWND hWnd, UINT nState, int nCx, int nCy) Parameters : hWnd Handle to the child window. nState State of resizing requested. nCx Size to be used for the "x" direction. nCy Size to be used for the "y" direction. Return Value: None. Description: Responds to WM_SIZE message and sets the internal data accordingly. Also forwards the message to DefMDIChildProc. --------------------------------------------------------------------------*/ static VOID Window_OnSize (HWND hWnd, UINT nState, int nCx, int nCy) { Window_ProcessSize (hWnd, nState, nCx, nCy); return; } /*----(Window_OnHScroll)---------------------------------------------------- Syntax : VOID Window_OnHScroll(HWND hWnd, HWND hWndCtl, UINT nCode, int npos) Parameters : hWnd Handle of a window. hWndCtl Not used. nCode Amount/Direction to be scrolled. npos The new position of the thumb. Return Value: None. Description: Scrolls the child window horizontally. --------------------------------------------------------------------------*/ static VOID Window_OnHScroll (HWND hWnd, HWND hWndCtl, UINT nCode, int nPos) { L_INT nScrollInc; UNREFERENCED_PARAMETER(hWndCtl); fInScroll = TRUE; switch (nCode) { case SB_LEFT: nScrollInc = -Data.nHScrollPos; break; case SB_RIGHT: nScrollInc = Data.nHScrollMax - Data.nHScrollPos; break; case SB_LINELEFT: nScrollInc = -Data.nHScrollStep; break; case SB_LINERIGHT: nScrollInc = Data.nHScrollStep; break; case SB_PAGELEFT: nScrollInc = -max (Data.nHScrollStep, (Data.cxClient - Data.nHScrollStep)); break; case SB_PAGERIGHT: nScrollInc = max (Data.nHScrollStep, (Data.cxClient - Data.nHScrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = nPos - Data.nHScrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-Data.nHScrollPos, min (nScrollInc, (Data.nHScrollMax - Data.nHScrollPos))); if(nScrollInc) { Data.nHScrollPos += nScrollInc; OffsetRect (&Data.rcView, -nScrollInc, 0); ScrollWindow (hWnd, -nScrollInc, 0, NULL, NULL); SetScrollPos (hWnd, SB_HORZ, Data.nHScrollPos, TRUE); UpdateWindow (hWnd); } fInScroll = FALSE; return; } /*----(Window_OnVScroll)---------------------------------------------------- Syntax : VOID Window_OnVScroll(HWND hWnd, HWND hWndCtl, UINT nCode, int nPos) Parameters : hWnd Handle of a window. hWndCtl Not used. nCode Amount/Direction to be scrolled. npos The new position of the thumb. Return Value: None. Description: Scrolls the child window vertically. --------------------------------------------------------------------------*/ static VOID Window_OnVScroll (HWND hWnd, HWND hWndCtl, UINT nCode, int nPos) { L_INT nScrollInc; UNREFERENCED_PARAMETER(hWndCtl); fInScroll = TRUE; switch (nCode) { case SB_BOTTOM: nScrollInc = Data.nVScrollMax - Data.nVScrollPos; break; case SB_TOP: nScrollInc = -Data.nVScrollPos; break; case SB_LINEDOWN: nScrollInc = Data.nVScrollStep; break; case SB_LINEUP: nScrollInc = -Data.nVScrollStep; break; case SB_PAGEDOWN: nScrollInc = max (Data.nVScrollStep, (Data.cyClient - Data.nVScrollStep)); break; case SB_PAGEUP: nScrollInc = -max (Data.nVScrollStep, (Data.cyClient - Data.nVScrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = nPos - Data.nVScrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-Data.nVScrollPos, min (nScrollInc, (Data.nVScrollMax - Data.nVScrollPos))); if(nScrollInc) { Data.nVScrollPos += nScrollInc; OffsetRect (&Data.rcView, 0, -nScrollInc); ScrollWindow (hWnd, 0, -nScrollInc, NULL, NULL); SetScrollPos (hWnd, SB_VERT, Data.nVScrollPos, TRUE); UpdateWindow (hWnd); } fInScroll = FALSE; return; } /*----(CleanOpenDlgParam)------------------------------------------------- Syntax: L_VOID CleanOpenDlgParam(LPOPENDLGPARAMS pFOParam) --------------------------------------------------------------------------*/ 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; } } /*----(GetOpenBitmapFile)------------------------------------------------- Syntax: L_BOOL GetOpenBitmapFile (HWND hWnd, LPSTR pFilename) Parameters: hWnd Handle to the window. pFilename Name of the file to open and get info from. Prototype: Draw.h Notes: This function will open a file and get image info. from it. --------------------------------------------------------------------------*/ L_BOOL GetOpenBitmapFile (HWND hWnd, LPTSTR pFilename) { static OPENDLGPARAMS FOParm; static OPENFILENAME OpenFileName; static L_BOOL fInit = FALSE; L_INT nRet; _fmemset(&FOParm, 0, sizeof(OPENDLGPARAMS)); FOParm.uStructSize = sizeof(OPENDLGPARAMS); FOParm.bShowLoadOptions = FALSE ; FOParm.bPreviewEnabled = TRUE; FOParm.uDlgFlags = DLG_OPEN_SHOW_PREVIEW | DLG_OPEN_SHOW_FILEINFO; OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.hwndOwner = hWnd; OpenFileName.lpstrFilter = NULL; OpenFileName.lpstrCustomFilter = NULL; OpenFileName.nMaxCustFilter = 0; OpenFileName.nFilterIndex = 1; OpenFileName.lpstrInitialDir = NULL; OpenFileName.lpstrTitle = TEXT("Open File"); OpenFileName.lpstrDefExt = NULL; OpenFileName.Flags = 0; if (!fInit) { OpenFileName.lpstrInitialDir = szImageDir; fInit = TRUE; } nRet = L_DlgOpen( hWnd, &OpenFileName, &FOParm); if(nRet == SUCCESS_DLG_OK) { nRet=FAILURE; if ( ( FOParm.pFileData != NULL ) && ( FOParm.nNumOfFiles > 0 ) ) { Data.FileInfo.uStructSize = sizeof(FILEINFO); nRet = L_FileInfo (FOParm.pFileData[ 0 ].szFileName, &Data.FileInfo, sizeof(FILEINFO), 0, NULL); if ( nRet != SUCCESS ) { MessageBox (hWnd, TEXT("File Error"), TEXT("Open Bitmap File"), MB_ICONEXCLAMATION | MB_OK); } else { lstrcpy(pFilename, FOParm.pFileData[ 0 ].szFileName); } } CleanOpenDlgParam(&FOParm); } return (nRet==SUCCESS)?TRUE:FALSE; } /*----[ImageLoad]----------------------------------------------------------- Syntax: L_BOOL ImageLoad (HWND hWnd, LPSTR pFileName) Parameters: hWnd Handle to the window. pFileName Name of the file to open and get info from. Prototype: Draw.h Notes: This function will load the image from a file. --------------------------------------------------------------------------*/ L_BOOL ImageLoad (HWND hWnd, LPTSTR lpFileName) { RECT rcClient; RECT rcWindow; HCURSOR hCursor; L_INT nFlags = LOADFILE_ALLOCATE | LOADFILE_STORE | LOADFILE_COMPRESSED; L_INT nRet; /* Free Bitmap and hPalette if already loaded */ if (Data.Bitmap.Flags.Allocated) L_FreeBitmap (&Data.Bitmap); if (Data.hPalette) { DeleteObject (Data.hPalette); Data.hPalette = NULL; } /* Get fileinfo of the file */ if (L_FileInfo (lpFileName, &Data.FileInfo,sizeof(FILEINFO), 0, NULL) != SUCCESS) { MessageBox (hWnd, TEXT("Error Reading Input File"), TEXT("Error"), MB_OK); return (0); } switch ( Data.FileInfo.BitsPerPixel) { case 2: case 3: case 4: case 5: case 6: case 7: MessageBox (hWnd, TEXT("Can't draw on image that has the following bits per pixels 2,3,4,5,6 or 7 "), TEXT("Error"), MB_OK); return (0); } /* reset the Data.Bitmap structure so that you don't get scrollbars */ L_InitBitmap (&Data.Bitmap,sizeof(Data.Bitmap), Data.FileInfo.Width, Data.FileInfo.Height, Data.FileInfo.BitsPerPixel); /* Snap the window to image */ ShowWindow (hWnd, SW_NORMAL); GetClientRect (hWnd, &rcClient); GetWindowRect (hWnd, &rcWindow); /* reset the window scrolls */ MoveWindow (hWnd, rcWindow.left, rcWindow.top, RECTWIDTH (&rcWindow) + INFOWIDTH(&Data.FileInfo) - RECTWIDTH (&rcClient), RECTHEIGHT (&rcWindow) + INFOHEIGHT(&Data.FileInfo) - RECTHEIGHT (&rcClient), TRUE); hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)); /* Change to WAIT */ /* Initialize Bitmap */ L_InitBitmap (&Data.Bitmap,sizeof(Data.Bitmap), Data.FileInfo.Width, Data.FileInfo.Height, Data.FileInfo.BitsPerPixel); /* Load the file to the bitmap */ if ((nRet = L_LoadFile (lpFileName, &Data.Bitmap,sizeof(Data.Bitmap), Data.Bitmap.BitsPerPixel, ORDER_BGR, nFlags, NULL, NULL, NULL, &Data.FileInfo)) != SUCCESS) { MessageBox (hWnd, TEXT("Error Loading File"), TEXT("Error"), MB_OK); } else { if( bmoveregion ) { KillTimer(hWnd, ID_REGIONEVENT); bmoveregion = FALSE; bmarkregion = TRUE; } SetRect( &Data.rcView, 0, 0, BITMAPWIDTH(&Data.Bitmap), BITMAPHEIGHT(&Data.Bitmap)); FORWARD_WM_QUERYNEWPALETTE (hWnd, SendMessage); InvalidateRect (hWnd, NULL, TRUE); } hCursor = SetCursor (hCursor); /* Change to original */ return (1); } /*----[Reset_Draw]----------------------------------------------------------- Syntax: L_VOID Reset_Draw(HWND hWnd) Parameters: hWnd Handle of the Window. Prototype: Draw.h Notes: This function will reset the flags used for drawing. --------------------------------------------------------------------------*/ L_VOID Reset_Draw (HWND hWnd) { if( bmoveregion ) { KillTimer(hWnd, ID_REGIONEVENT); InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); L_FreeBitmapRgn(&Data.Bitmap); } xAnchor = yAnchor = -1; xold = yold = -1; bpoint = bline = brectangle = bellipse = FALSE; btext = bmarkregion = bmoveregion = bDraw = FALSE; } /*----[SaveBitmapFile]------------------------------------------------------ Syntax: L_BOOL SaveBitmapFile (HWND hWnd, pBITMAPHANDLE pBitmapHandle) Parameters: hWnd Handle of the Window. pBitmapHandle Bitmap Handle of the image to save. Prototype: Draw.h Notes: This function will get the filename to save the image to. --------------------------------------------------------------------------*/ L_BOOL SaveBitmapFile (HWND hWnd, pBITMAPHANDLE pBitmapHandle) { HCURSOR hCursor; L_INT nRet; static OPENFILENAME OpenFileName; SAVEFILEOPTION SaveFileOption; static L_UINT uSaveMulti = FALSE; static SAVEDLGPARAMS FSParm; FILEJ2KOPTIONS FileJ2KOptions; pDIMENSION pOldResolutions=NULL; pDIMENSION pJBIGResolutions=NULL; TCHAR buf[50]; static L_BOOL fInit = FALSE; if (!fInit) { OpenFileName.lpstrInitialDir = szImageDir; fInit = TRUE; } memset(&FileJ2KOptions,0,sizeof(FILEJ2KOPTIONS)); OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.lpstrInitialDir = NULL; OpenFileName.lpstrTitle = TEXT("Save a File"); OpenFileName.nFilterIndex = 1; OpenFileName.Flags = 0; FSParm.uStructSize = sizeof(SAVEDLGPARAMS); FSParm.nQFactor = 2; FSParm.nPageNumber = 1; FSParm.uSaveMulti = uSaveMulti; FSParm.uDlgFlags = DLG_SAVE_ENABLESIZING | DLG_SAVE_SHOW_FILEOPTIONS_MULTIPAGE| DLG_SAVE_SHOW_FILEOPTIONS_PROGRESSIVE | DLG_SAVE_SHOW_FILEOPTIONS_QFACTOR | DLG_SAVE_SHOW_FILEOPTIONS_STAMP| DLG_SAVE_SHOW_FILEOPTIONS_BASICJ2KOPTIONS| DLG_SAVE_SHOW_FILEOPTIONS_J2KOPTIONS; nRet = L_DlgSave( hWnd,&OpenFileName,&FSParm); if(nRet == SUCCESS_DLG_OK) { L_GetDefaultSaveFileOption(&SaveFileOption, sizeof(SAVEFILEOPTION)); SaveFileOption.Flags &= ~(ESO_REPLACEPAGE|ESO_INSERTPAGE); switch(FSParm.uSaveMulti) { case MULTIPAGE_OPERATION_OVERWRITE: SaveFileOption.PageNumber = 1; break; case MULTIPAGE_OPERATION_APPEND: SaveFileOption.PageNumber = 2; break; case MULTIPAGE_OPERATION_REPLACE: SaveFileOption.PageNumber = FSParm.nPageNumber; SaveFileOption.Flags |= ESO_REPLACEPAGE; break; case MULTIPAGE_OPERATION_INSERT: SaveFileOption.PageNumber = FSParm.nPageNumber; SaveFileOption.Flags |= ESO_INSERTPAGE; break; } hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)); if((FSParm.nFormat == FILE_J2K)|| (FSParm.nFormat == FILE_JP2)|| (FSParm.nFormat == FILE_CMW)|| (FSParm.nFormat == FILE_TIF_J2K)|| (FSParm.nFormat == FILE_TIF_CMW)) { /*Restore the old J2K Options*/ L_GetJ2KOptions(&FileJ2KOptions,sizeof(FILEJ2KOPTIONS)); L_SetJ2KOptions(&FSParm.FileJ2KOptions); } nRet = L_SaveBitmap( FSParm.szFileName, pBitmapHandle, FSParm.nFormat, FSParm.nBitsPerPixel, FSParm.nQFactor, &SaveFileOption); SetCursor (hCursor); if((FSParm.nFormat == FILE_J2K)|| (FSParm.nFormat == FILE_JP2)|| (FSParm.nFormat == FILE_CMW)|| (FSParm.nFormat == FILE_TIF_J2K)|| (FSParm.nFormat == FILE_TIF_CMW)) { /*Restore the old J2K Options*/ L_SetJ2KOptions(&FileJ2KOptions); } if(nRet == SUCCESS) { return TRUE; } else { wsprintf (buf, TEXT("ERROR %d saving the file %s."), nRet, (LPTSTR) FSParm.szFileName); MessageBox (hWnd, buf, TEXT("ERROR"), MB_OK); } } return (FALSE); } COLORREF Color (int ncolor) { switch (ncolor) { case 0: return (RGB (0, 0, 0)); case 1: return (RGB (255, 255, 255)); case 2: return (RGB (255, 0, 0)); case 3: return (RGB (0, 255, 0)); case 4: return (RGB (0, 0, 255)); } return (RGB (0, 0, 0)); } /*----[TextDialogProc]------------------------------------------------------ Syntax: L_BOOL TextDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) Parameters: hDlg The handle of the dialog box. message Message to be processed. wParam Windows word parameter. lParam Windows long parameter. Prototype: Draw.h Description: Processes Text dialog box messages. --------------------------------------------------------------------------*/ L_BOOL CALLBACK L_EXPORT TextDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { lParam = lParam; switch (message) { case WM_INITDIALOG: SetDlgItemText (hDlg, IDC_EDIT1, szText); return TRUE; case WM_COMMAND: switch (wParam) { case IDOK: GetDlgItemText (hDlg, IDC_EDIT1, szText, sizeof (szText)); EndDialog (hDlg, 0); return TRUE; case IDCANCEL: EndDialog (hDlg, 0); return TRUE; } break; } return (FALSE); } /*----[ChangeRegion]------------------------------------------------------ Syntax: L_INT ChangeRegion (HWND hWnd, L_INT id) Parameters: hWnd The window where the bitmap is drawn. id The menu id determining the processing to be done on the region Prototype: Draw.h Notes: This function will change the region, possibly changing its size. --------------------------------------------------------------------------*/ L_INT ChangeRegion( HWND hWnd, L_INT id ) { L_INT nRet/*, nValue*/; L_INT nNewWidth, nNewHeight; L_INT xCenter, yCenter; HDC hdc; //ROTATEPARM RotateParm; //RESIZEPARM ResizeParm; HCURSOR hOldCursor; XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = XForm.nXScalarDen = XForm.nYScalarNum = XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; L_SetBitmapRgnHandle( &bmFloater, &XForm, hrgnRegion, L_RGN_SET ); switch(id) { case IDM_ROTATEREGION: { ROTATEDLGPARAMS DlgParams; memset(&DlgParams, 0, sizeof(DlgParams)); DlgParams.pBitmap = &bmFloater; DlgParams.uStructSize = sizeof ( ROTATEDLGPARAMS ) ; DlgParams.nAngle = 0 ; DlgParams.bResize = TRUE ; DlgParams.uDlgFlags = DLG_ROTATE_SHOW_PREVIEW| DLG_ROTATE_SHOW_RESIZE | DLG_ROTATE_SHOW_BACKCOLOR; nRet = L_DlgRotate ( hWnd, &DlgParams ); if( nRet == SUCCESS_DLG_OK) { nRet = L_RotateBitmap( &bmFloater, DlgParams.nAngle , DlgParams.bResize, DlgParams.crBack ); } break; } case IDM_FLIPREGION: nRet = L_FlipBitmap( &bmFloater ); break; case IDM_REVERSEREGION: nRet = L_ReverseBitmap( &bmFloater ); break; case IDM_RESIZEREGION: { RESIZEDLGPARAMS DlgParams; memset(&DlgParams, 0 ,sizeof(DlgParams)); DlgParams.uStructSize = sizeof(RESIZEDLGPARAMS); DlgParams.pBitmap = &bmFloater; DlgParams.uOriginalWidth = BITMAPWIDTH(&bmFloater); DlgParams.uOriginalHeight = BITMAPHEIGHT(&bmFloater); DlgParams.uOriginalBitsPerPixel = bmFloater.BitsPerPixel; DlgParams.uOriginalResolutionX = bmFloater.XResolution; DlgParams.uOriginalResolutionY = bmFloater.YResolution; DlgParams.uNewWidth = BITMAPWIDTH(&bmFloater); DlgParams.uNewHeight = BITMAPHEIGHT(&bmFloater); DlgParams.uNewResolutionX = bmFloater.XResolution; DlgParams.uNewResolutionY = bmFloater.YResolution; DlgParams.uResize = SIZE_NORMAL ; DlgParams.uDlgFlags = DLG_RESIZE_SHOW_PERCENTAGE | DLG_RESIZE_SHOW_IDENTICALVALUE | DLG_RESIZE_SHOW_MAINTAINASPECT | DLG_RESIZE_SHOW_RESOLUTIONGRP; nRet = L_DlgResize ( hWnd, &DlgParams ) ; if(nRet == SUCCESS_DLG_OK) { nRet = L_SizeBitmap ( &bmFloater, DlgParams.uNewWidth, DlgParams.uNewHeight, DlgParams.uResize ); } break; } case IDM_BRIGHTNESSREGION: { BRIGHTNESSDLGPARAMS DlgParams; memset(&DlgParams,0,sizeof(DlgParams)); DlgParams.uStructSize = sizeof(BRIGHTNESSDLGPARAMS); DlgParams.pBitmap = &bmFloater; DlgParams.nChange = 0 ; DlgParams.uDlgFlags = DLG_BRIGHTNESS_SHOW_PREVIEW| DLG_BRIGHTNESS_SHOW_TOOL_ZOOMLEVEL ; nRet = L_DlgBrightness ( hWnd, &DlgParams ) ; if (nRet == SUCCESS_DLG_OK) { nRet = L_ChangeBitmapIntensity (&bmFloater, DlgParams.nChange); } break; } case IDM_CONTRASTREGION: { CONTRASTDLGPARAMS DlgParams; memset(&DlgParams,0,sizeof(DlgParams)); DlgParams.uStructSize = sizeof(CONTRASTDLGPARAMS); DlgParams.pBitmap = &bmFloater; DlgParams.nChange = 0; DlgParams.uDlgFlags = DLG_CONTRAST_SHOW_PREVIEW| DLG_CONTRAST_SHOW_TOOL_ZOOMLEVEL ; nRet = L_DlgContrast ( hWnd, &DlgParams ) ; if (nRet == SUCCESS_DLG_OK) { nRet = L_ChangeBitmapContrast (&bmFloater, DlgParams.nChange); } break; } } switch(nRet) { case SUCCESS_DLG_EXPORTANDEXIT: case SUCCESS_DLG_EXIT: case SUCCESS_DLG_CLOSE: case SUCCESS_DLG_CANCEL: return 0; } if( nRet != SUCCESS ) { MessageBox (hWnd, TEXT("ChangeRegion failed"), TEXT("ERROR"), MB_OK|MB_ICONHAND); return nRet; } hOldCursor = SetCursor( LoadCursor(NULL, IDC_WAIT) ); /* Update the new region */ DeleteObject( hrgnRegion ); L_GetBitmapRgnHandle( &bmFloater, &XForm, &hrgnRegion ); L_FreeBitmapRgn( &bmFloater); L_FreeBitmapRgn( &Data.Bitmap); /* the size of the region has changed. Redo the bmSave bitmap */ /* Restore the Data.Bitmap bitmap. Now the screen doesn't accurately reflect the bitmap */ L_CombineBitmap( &Data.Bitmap, xMoveDest, yMoveDest, nMoveWidth, nMoveHeight, &bmSave, 0, 0, L_SRCCOPY ); nNewWidth = bmFloater.Width; nNewHeight = bmFloater.Height; /* keep the center of the region in the same place */ xCenter = xMoveDest + nMoveWidth / 2; yCenter = yMoveDest + nMoveHeight / 2; xMoveDest = xMoveSrc = xCenter - nNewWidth / 2; yMoveDest = yMoveSrc = yCenter - nNewHeight / 2; nMoveWidth = bmFloater.Width; nMoveHeight = bmFloater.Height; /* free the old save bitmap */ L_FreeBitmap( &bmSave ); /* Save the region background. Normally I would want to call L_CopyBitmapRect but I must make sure the parameters are within the bitmap boundaries. Just calling L_CopyBitmapRect(&bmSave,&Data.Bitmap,xMoveSrc,yMoveSrc,nMoveWidth,nMoveHeight) will not always work if I stepped outside the bitmap during resizing. I will have to allocate the bitmap myself and call L_CombineBitmap instead because it does more checks */ L_InitBitmap( &bmSave, sizeof(BITMAPHANDLE),nMoveWidth, nMoveHeight, Data.Bitmap.BitsPerPixel ); bmSave.ViewPerspective = TOP_LEFT; /* I work easier with TOP_LEFT images */ bmSave.Order = Data.Bitmap.Order; /* I work easier with TOP_LEFT images */ nRet = L_AllocateBitmap( &bmSave, TYPE_CONV ); if( nRet != SUCCESS ) { SetCursor( hOldCursor ); MessageBox (hWnd, TEXT("Not enough memory to allocate background bitmap"), TEXT("ERROR"), MB_OK|MB_ICONHAND); return nRet; } /* copy the palette */ if(Data.Bitmap.BitsPerPixel <= 8) { L_CopyBitmapPalette(&bmSave, &Data.Bitmap); } /* do the actual saving of the background */ L_CombineBitmap( &bmSave, 0, 0, nMoveWidth, nMoveHeight, &Data.Bitmap, xMoveSrc, yMoveSrc, L_SRCCOPY ); /* now create the floater and save DDBs */ hdc = GetDC(hWnd); if( hbmSave ) DeleteObject( hbmSave ); hbmSave = L_ConvertToDDB( hdc, &bmSave ); if( hbmFloater ) DeleteObject( hbmFloater ); hbmFloater = L_ConvertToDDB( hdc, &bmFloater ); /* set the region in the original bitmap so that only the floater gets copied and the moving frame gets shown */ /* Note: the following statements XForm.nXOffset = xMoveSrc; XForm.nYOffset = yMoveSrc; L_SetBitmapRgnHandle( &Data.Bitmap, &XForm, hrgnRegion, L_RGN_SET ); are equivalent to L_SetBitmapRgnHandle and L_OffsetBitmapRgn */ XForm.nXOffset = 0; XForm.nYOffset = 0; L_SetBitmapRgnHandle( &Data.Bitmap, &XForm, hrgnRegion, L_RGN_SET ); /* again, L_OffsetBitmapRgn uses (row,col) parameters which is (y,x) */ L_OffsetBitmapRgn(&Data.Bitmap,yMoveSrc,xMoveSrc); /* blend the floater into the bitmap */ L_CombineBitmap( &Data.Bitmap, xMoveSrc, yMoveSrc, nMoveWidth, nMoveHeight, &bmFloater, 0, 0, L_SRCCOPY ); /* repaint the whole image */ InvalidateRect( hWnd, NULL, FALSE ); SetCursor( hOldCursor ); return SUCCESS; } /*----[OutlineBitmapRgn]--------------------------------------------------- Syntax: L_VOID OutlineBitmapRgn(HWND hWnd, HDC hdc) Parameters: hWnd The window where the bitmap is drawn. hdc The device context of the window where the frame is to be drawn. Prototype: Draw.h Notes: This function will draw the outline of the region. Using different brushes, it creates the impression of moving the frame. --------------------------------------------------------------------------*/ L_VOID OutlineBitmapRgn(HWND hWnd, HDC hdc) { HDC hdcDraw; RGNXFORM XForm; if( bmoveregion && L_BitmapHasRgn(&Data.Bitmap) ) { if(hdc) hdcDraw = hdc; else hdcDraw = GetDC(hWnd); XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = RECTWIDTH(&Data.rcView); XForm.nXScalarDen = BITMAPWIDTH(&Data.Bitmap); XForm.nYScalarNum = RECTHEIGHT(&Data.rcView); XForm.nYScalarDen = BITMAPHEIGHT(&Data.Bitmap); XForm.nXOffset = Data.rcView.left; XForm.nYOffset = Data.rcView.top; L_FrameBitmapRgn(hdcDraw, &Data.Bitmap, &XForm, Data.uRegionMask); if(!hdc) ReleaseDC(hWnd, hdcDraw); } } /*----[HiliteMark]---------------------------------------------------------- Syntax: L_VOID HiliteMark(HWND hWnd, L_BOOL fUpdate) Parameters: hWnd The window where the bitmap is drawn. fUpdate Specifies whether you just update an existing mark or draw a new one (meaningful only when using polygonal regions). Prototype: Draw.h Notes: This function will draw the outline of the region. As opposed to OutlineBitmapRgn, this is just used to help select a region. --------------------------------------------------------------------------*/ L_VOID HiliteMark(HWND hWnd, L_BOOL fUpdate) { HDC hdc; HBRUSH hBrush; HPEN hPen; L_INT nDrawMode; HRGN hRgn; if(nNextPt <= 1) return; hdc = GetDC(hWnd); hBrush = SelectObject (hdc, GetStockObject (NULL_BRUSH)); hPen = SelectObject (hdc, GetStockObject(WHITE_PEN)); hRgn = CreateRectRgnIndirect(&Data.rcView); SelectObject(hdc, hRgn); DeleteObject(hRgn); nDrawMode = GetROP2 (hdc); SetROP2 (hdc, R2_NOT); /* All the x values are relative to the bitmap set the viewport of the DC to match the bitmap */ SetViewportOrgEx( hdc, Data.rcView.left, Data.rcView.top, NULL ); switch(nRegionTool) { case IDM_TOOLRECT: Rectangle(hdc, min(pptRegion[0].x, pptRegion[1].x), min(pptRegion[0].y, pptRegion[1].y), max(pptRegion[0].x, pptRegion[1].x), max(pptRegion[0].y, pptRegion[1].y)); break; case IDM_TOOLRNDRECT: RoundRect(hdc, pptRegion[0].x, pptRegion[0].y, pptRegion[1].x, pptRegion[1].y, abs(pptRegion[0].x - pptRegion[1].x) / 4, abs(pptRegion[0].y - pptRegion[1].y) / 4); break; case IDM_TOOLELLIPSE: Ellipse(hdc, pptRegion[0].x, pptRegion[0].y, pptRegion[1].x, pptRegion[1].y); break; case IDM_TOOLFREEHAND: if(fUpdate) Polyline(hdc, &pptRegion[nNextPt - 2], 2); else Polyline(hdc, pptRegion, nNextPt); break; } SetROP2 (hdc, nDrawMode); SelectObject(hdc, hBrush); SelectObject(hdc, hPen); ReleaseDC(hWnd, hdc); } /*----[CreateRegionBitmaps]------------------------------------------------- Syntax: L_INT CreateRegionBitmaps( HWND hWnd ) Parameters: hWnd The window where the bitmap is drawn. Prototype: Draw.h Notes: This function will allocate the bitmaps and DDBs used to move the floater bitmap around. --------------------------------------------------------------------------*/ L_INT CreateRegionBitmaps( HWND hWnd ) { HDC hdc; hdc = GetDC(hWnd); /* delete the previous region */ if( hrgnRegion ) DeleteObject( hrgnRegion ); /* get the region from original bitmap. Current offset is xMoveSrc,yMoveSrc and I want it at 0,0 */ XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = XForm.nXScalarDen = XForm.nYScalarNum = XForm.nYScalarDen = 1; XForm.nXOffset = - xMoveSrc; XForm.nYOffset = - yMoveSrc; L_GetBitmapRgnHandle( &Data.Bitmap, &XForm, &hrgnRegion ); /* clear the region from the source bitmap */ L_FreeBitmapRgn(&Data.Bitmap); /* --------------- START CREATING THE FLOATING BITMAPS --------- */ /* free the previous floater bitmap */ if( bmFloater.Flags.Allocated ) L_FreeBitmap( &bmFloater ); /* create the floater bitmap */ L_CopyBitmapRect( &bmFloater, &Data.Bitmap,sizeof(BITMAPHANDLE), xMoveSrc, yMoveSrc, nMoveWidth, nMoveHeight ); /* create the floater DDB */ if( hbmFloater ) DeleteObject( hbmFloater ); hbmFloater = L_ConvertToDDB( hdc, &bmFloater ); /* --------------- the floating bitmaps are created ------------- */ /* ------- START CREATING THE BACKGROUND BITMAPS ------- */ /* create the background bitmap */ if( bmSave.Flags.Allocated ) L_FreeBitmap( &bmSave ); /* create the save bitmap. Now, it is exactly as the floater */ L_CopyBitmap( &bmSave, &bmFloater ,sizeof(BITMAPHANDLE)); if( hbmSave ) DeleteObject( hbmSave ); hbmSave = L_ConvertToDDB( hdc, &bmSave ); /* ------- the background bitmaps are created --------- */ /* set the floater back into the source bitmap */ /* This is because I have just selected the region and I will be displaying it using the timer messages */ XForm.nXOffset = xMoveSrc; XForm.nYOffset = yMoveSrc; L_SetBitmapRgnHandle(&Data.Bitmap, &XForm, hrgnRegion, L_RGN_SET); if( !hbmFloater || !hbmSave || !bmFloater.Flags.Allocated || !bmSave.Flags.Allocated || !hrgnRegion) MessageBox( hWnd, TEXT("Error allocating bitmaps"), TEXT(""), MB_OK ); /* create the background DDB */ ReleaseDC( hWnd, hdc ); return SUCCESS; } /*---[ExtractCommandData]---------------------------------------------------- Syntax: L_BOOL ExtractCommandData( ); Parameters: None. ProtoType: draw.c Notes: - This procedure is responsible for extracting the dir name 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 ; } memset (szImageDir, 0, sizeof(szImageDir)); lstrcpyn ( szImageDir, pszFirst - 1, ( nStringLen - nFirstPos ) ) ; return TRUE; }