Implementing the Paint Automation Initializing, Creating and Freeing

Take the following steps to implement paint automation:

  1. Start Visual C++, version 2005.

  2. Select the File->New menu option, and in the dialog box, select Project.

  3. In the New Project dialog box, make sure to select Visual C++ Win32 from the tree on the left of the dialog, and select Win32 Project as the project template.
    Give the Solution Name "Tutorial_Automation" and the project the name "Tutorial_Automation" and click OK.

  4. After the Win32 Application Wizard initializes, click Finish.

  5. In the Solution Explorer, browse to the Tutorial_Automation.rc file and double-click it. It will open the resource file in the View area.

  6. To add a new menu item in the File menu, open the File menu in the resource file you just opened in the view area, select a new location at the bottom of the menu, and type Open to add the new menu item Open.

  7. In stdafx.h add the following header after #include<tchar.h>: (keep in mind, you may need to change the path to where the header files reside):

    #include <commdlg.h>     
    #include "C:\LEADTOOLS 20\Include\l_bitmap.h" 
    #include "C:\LEADTOOLS 20\Include\ltdlg.h" 
    #include "C:\LEADTOOLS 20\Include\ltcon.h" 
    #include "C:\LEADTOOLS 20\Include\lttlb.h" 
    #include "C:\LEADTOOLS 20\Include\ltpnt.h" 
    #include "C:\LEADTOOLS 20\Include\ltaut.h" 

  8. Create a new file called Imports.cpp and place it beside your project files.
    1. In the Project Workspace, click the Solution Explorer tab.
    2. Double-click the Tutorial_Automation folder to open it.
    3. Right-click the Source files folder and select Add New item.
    4. Right-click the Source file.
    5. Expand the Visual C++ tree, if it is not already expanded.
    6. Select Code from the sub-tree.
    7. Select C++ File (.cpp) from the right window.
    8. In the Name text box, specify Imports.
    9. Click OK.
    10. Double-click the imports.cpp in the Solution Explorer and add the following lines: (keep in mind, the path to where the header files reside may need to be changed)
      #if defined(FOR_WIN64) 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\Ltkrn_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\Ltdis_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\Ltdlgkrn_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\Ltdlgfile_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\Ltfil_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\ltaut_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\ltcon_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\lttlb_x.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\x64\\ltpdg_x.lib") 
      #elif defined(FOR_WIN32)  
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\Ltkrn_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\Ltdis_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\Ltdlgkrn_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\Ltdlgfile_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\Ltfil_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\ltaut_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\ltcon_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\lttlb_u.lib") 
         #pragma comment(lib, "C:\\LEADTOOLS 20\\Lib\\CDLLVC10\\Win32\\ltpdg_u.lib") 
      #endif // #if defined(FOR_WIN64) 
  9. Add the following functions in Tutorial_Automation.cpp right before WndProc procedure.
    static L_VOID OnSize(HWND hWnd, 
    pBITMAPHANDLE pBitmap, 
    LPRECT prcView, 
    L_INT cx, 
    L_INT cy, 
    L_INT nScalarNum, 
    L_INT nScalarDen, 
    L_INT *pnHScroll, 
    L_INT *pnVScroll) 
    { 
       SCROLLINFO si ; 
       L_INT      nXOffset, nYOffset ; 
        
        
       if ( NULL != pBitmap && pBitmap->Flags.Allocated ) 
       { 
          si.cbSize = sizeof ( SCROLLINFO ) ; 
          si.fMask  = SIF_ALL ; 
           
          // vertical scroll. 
          GetScrollInfo ( hWnd, SB_VERT, &si ) ; 
          si.nMin  = 0 ; 
          si.nMax  = BITMAPHEIGHT ( pBitmap ) ; 
          si.nPage = MulDiv ( cy, nScalarDen, nScalarNum ) ; 
           
          SetScrollInfo ( hWnd, SB_VERT, &si, TRUE ) ; 
           
          GetScrollInfo ( hWnd, SB_VERT, &si ) ; 
           
          *pnVScroll = si.nPos ; 
           
          // horizontal scroll 
          GetScrollInfo ( hWnd, SB_HORZ, &si ) ; 
          si.nMin  = 0 ; 
          si.nMax  = BITMAPWIDTH ( pBitmap ) ; 
          si.nPage = MulDiv ( cx, nScalarDen, nScalarNum ) ; 
           
          SetScrollInfo ( hWnd, SB_HORZ, &si, TRUE ) ; 
           
          GetScrollInfo ( hWnd, SB_HORZ, &si ) ; 
           
          *pnHScroll = si.nPos ; 
       } 
       else 
       { 
          si.cbSize = sizeof ( SCROLLINFO ) ; 
          si.fMask  = SIF_RANGE ; 
          si.nMin   = 0 ; 
          si.nMax   = 0 ; 
           
          SetScrollInfo ( hWnd, SB_VERT, &si, TRUE ) ; 
          SetScrollInfo ( hWnd, SB_HORZ, &si, TRUE ) ; 
           
          *pnHScroll = 0 ; 
          *pnVScroll = 0 ; 
       } 
        
       // set the painting rectangle. 
       SetRect ( prcView, 0, 0, BITMAPWIDTH ( pBitmap ), BITMAPHEIGHT ( pBitmap ) ) ; 
        
       if ( nScalarDen > nScalarNum ) 
       { 
          nXOffset = MulDiv ( *pnHScroll, nScalarDen, nScalarNum ) ; 
          nYOffset = MulDiv ( *pnVScroll, nScalarDen, nScalarNum ) ; 
       } 
       else 
       { 
          nXOffset = *pnHScroll ; 
          nYOffset = *pnVScroll ; 
       } 
        
       OffsetRect ( prcView, - nXOffset, - nYOffset ) ; 
        
       prcView->left   = MulDiv ( prcView->left,   nScalarNum, nScalarDen ) ; 
       prcView->top    = MulDiv ( prcView->top,    nScalarNum, nScalarDen ) ; 
       prcView->right  = MulDiv ( prcView->right,  nScalarNum, nScalarDen ) ; 
       prcView->bottom = MulDiv ( prcView->bottom, nScalarNum, nScalarDen ) ; 
    } 
    L_VOID OnHScroll(HWND hWnd, 
    L_UINT code, 
    L_INT nScalarNum, 
    L_INT nScalarDen, 
    LPRECT prcView, 
    L_INT *pnHScroll, 
    L_INT *pnVScroll) 
    { 
       SCROLLINFO si ; 
        
        
       si.cbSize = sizeof (SCROLLINFO) ; 
       si.fMask  = SIF_ALL ; 
       GetScrollInfo (hWnd, SB_HORZ, &si) ; 
        
       *pnHScroll = si.nPos ; 
        
       switch ( code ) 
       { 
          case SB_LINELEFT: 
          si.nPos -= 1 ; 
          break ; 
           
          case SB_LINERIGHT: 
          si.nPos += 1 ; 
          break ; 
           
          case SB_PAGELEFT: 
          si.nPos -= si.nPage ; 
          break ; 
           
          case SB_PAGERIGHT: 
          si.nPos += si.nPage ; 
          break ; 
           
          case SB_THUMBTRACK: 
          si.nPos = si.nTrackPos ; 
          break ; 
           
    default: 
          break ; 
       } 
        
       si.fMask = SIF_POS; 
       SetScrollInfo (hWnd, SB_HORZ, &si, TRUE) ; 
       GetScrollInfo (hWnd, SB_HORZ, &si) ; 
        
       if ( si.nPos != *pnHScroll ) 
       { 
          L_INT dxUpdate ; 
           
           
          // update screen. 
          if ( nScalarDen < nScalarNum ) 
          { 
             dxUpdate = MulDiv ( ( *pnHScroll - si.nPos ), nScalarNum, nScalarDen ) ; 
          } 
          else 
          { 
             dxUpdate = *pnHScroll - si.nPos ; 
          } 
           
          // update screen. 
          OffsetRect ( prcView, dxUpdate, 0 ) ; 
           
          ScrollWindow ( hWnd, dxUpdate, 0, NULL, NULL ) ; 
           
          *pnHScroll = si.nPos ; 
           
          UpdateWindow ( hWnd ) ; 
       } 
    } 
    L_VOID OnVScroll(HWND hWnd, 
    L_UINT code, 
    L_INT nScalarNum, 
    L_INT nScalarDen, 
    LPRECT prcView, 
    L_INT *pnHScroll, 
    L_INT *pnVScroll) 
    { 
       SCROLLINFO si; 
       si.cbSize = sizeof ( SCROLLINFO ) ; 
       si.fMask  = SIF_ALL ; 
       GetScrollInfo (hWnd, SB_VERT, &si) ; 
        
       *pnVScroll = si.nPos ; 
        
       switch ( code ) 
       { 
          case SB_LINEUP: 
          si.nPos -= 1 ; 
          break ; 
           
          case SB_LINEDOWN: 
          si.nPos += 1 ; 
          break ; 
           
          case SB_PAGEUP: 
          si.nPos -= si.nPage ; 
          break ; 
           
          case SB_PAGEDOWN: 
          si.nPos += si.nPage ; 
          break ; 
           
          case SB_THUMBTRACK: 
          si.nPos = si.nTrackPos ; 
          break ; 
           
    default: 
          break ; 
       } 
        
       si.fMask = SIF_POS ; 
       SetScrollInfo ( hWnd, SB_VERT, &si, TRUE ) ; 
       GetScrollInfo ( hWnd, SB_VERT, &si ) ; 
        
       if ( si.nPos != *pnVScroll ) 
       { 
          L_INT dyUpdate ; 
           
           
          // update screen. 
          if ( nScalarDen < nScalarNum ) 
          { 
             dyUpdate = MulDiv ( ( *pnVScroll - si.nPos ), nScalarNum, nScalarDen ) ; 
          } 
          else 
          { 
             dyUpdate = *pnVScroll - si.nPos ; 
          } 
           
          // update screen. 
          OffsetRect ( prcView, 0, dyUpdate ) ; 
           
          ScrollWindow ( hWnd, 0, dyUpdate, NULL, NULL ) ; 
           
          *pnVScroll = si.nPos ; 
           
          UpdateWindow ( hWnd ) ; 
       } 
    } 
    L_VOID OnPaint(HWND hWnd, 
    pBITMAPHANDLE pBitmap, 
    LPRECT prcView, 
    HPALETTE hPalette) 
    { 
       HDC hDC ; 
       PAINTSTRUCT ps ; 
       HPALETTE hOldPal = NULL  ; 
        
        
       hDC = BeginPaint (hWnd, &ps) ; 
        
       if ( pBitmap->Flags.Allocated ) 
       { 
          if ( hPalette ) 
          { 
             hOldPal = SelectPalette ( hDC, hPalette, TRUE ) ; 
             RealizePalette ( hDC ) ; 
          } 
           
          L_PaintDC  ( hDC, pBitmap, NULL, NULL, prcView, &ps.rcPaint, SRCCOPY ) ; 
           
          if ( NULL != hOldPal ) 
          { 
             SelectPalette ( hDC, hOldPal, TRUE ) ; 
          } 
       } 
        
       EndPaint (hWnd, &ps) ; 
    } 
    static L_BOOL OnOpen ( HWND hWnd, pBITMAPHANDLE pBitmap ) 
    { 
       static L_INT  nOpenIndex = 0 ; 
       OPENFILENAME  OpenFileName ; 
       L_TCHAR       szFile [ MAX_PATH ] = TEXT("\0") ; 
       L_TCHAR       szFileTitle [ MAX_PATH ] = TEXT("\0") ; 
       L_TCHAR       szOpenFileFilter [ ] = {TEXT("ALL\0")TEXT("*.*\0")} ; 
       OPENDLGPARAMS OpenDlgParams ; 
       BITMAPHANDLE  hThumb ; 
       L_INT         nRet; 
       memset ( &OpenDlgParams, 0, sizeof ( OPENDLGPARAMS ) ) ; 
       lstrcpy ( szFile, TEXT("") ) ; 
       L_InitBitmap  ( pBitmap, sizeof(BITMAPHANDLE), 0, 0, 0 ) ; 
       L_InitBitmap ( &hThumb, sizeof(BITMAPHANDLE), 0, 0, 0 ) ; 
       OpenFileName.lStructSize = sizeof(OPENFILENAME); 
       OpenFileName.hwndOwner = hWnd; 
       OpenFileName.lpstrFilter = szOpenFileFilter; 
       OpenFileName.lpstrCustomFilter = NULL; 
       OpenFileName.nMaxCustFilter = 0; 
       OpenFileName.nFilterIndex = nOpenIndex; 
       OpenFileName.nMaxFile = sizeof(szFile); 
       OpenFileName.lpstrFile = szFile; 
       OpenFileName.nMaxFileTitle = sizeof(szFileTitle); 
       OpenFileName.lpstrFileTitle = szFileTitle; 
       OpenFileName.lpstrInitialDir = NULL; 
       OpenFileName.lpstrTitle = TEXT("Open a File"); 
       OpenFileName.nFileOffset = 0; 
       OpenFileName.nFileExtension = 0; 
       OpenFileName.lpstrDefExt = NULL; 
       OpenFileName.lpfnHook = NULL; 
       OpenFileName.Flags = OFN_LONGNAMES ; 
       OpenDlgParams.uStructSize      = sizeof(OPENDLGPARAMS); 
       OpenDlgParams.bPreviewEnabled  = TRUE; 
       OpenDlgParams.uDlgFlags        = DLG_OPEN_SHOW_PREVIEW | 
       DLG_OPEN_SHOW_FILEINFO; 
       nRet =  L_DlgOpen ( hWnd, &OpenFileName, &OpenDlgParams ); 
       if (nRet == SUCCESS_DLG_OK) 
       { 
          nOpenIndex = OpenFileName.nFilterIndex; 
          L_FreeBitmap  ( &hThumb ) ; 
          L_LoadBitmap (OpenDlgParams.pFileData[0].szFileName, pBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, NULL, NULL); 
          L_ChangeBitmapViewPerspective  ( NULL, pBitmap, sizeof(BITMAPHANDLE), TOP_LEFT ); 
          return TRUE ; 
       } 
       else 
       { 
          return FALSE ; 
       } 
    } 
  10. Replace the existing WndProc function with the following code:
    LRESULT CALLBACK WndProc( HWND hWnd, L_UINT uMessage, WPARAM wParam, LPARAM lParam ) 
    { 
       static BITMAPHANDLE hBitmap ; 
       static RECT rcView ; 
       static HPALETTE hPalette = NULL ; 
       static L_INT nVScroll = 0 ; 
       static L_INT nHScroll = 0 ; 
       static L_INT nScalarNum = 1, nScalarDen = 1 ; 
       switch( uMessage ) 
       { 
          case WM_CREATE: 
          L_DlgInit (DLG_INIT_COLOR); 
          return 0L ; 
           
          case WM_DESTROY: 
          if ( hBitmap.Flags.Allocated ) 
          { 
             L_FreeBitmap  ( &hBitmap ) ; 
          } 
           
          if ( hPalette ) 
          { 
             DeleteObject( hPalette ) ; 
          } 
          PostQuitMessage ( 0 ) ; 
           
          return 0L ; 
           
          case WM_SIZE: 
          OnSize ( hWnd, 
          &hBitmap, 
          &rcView, 
          LOWORD ( lParam ), 
          HIWORD ( lParam ), 
          nScalarNum, 
          nScalarDen, 
          &nHScroll, 
          &nVScroll ) ; 
          break ; 
           
          case WM_HSCROLL: 
          OnHScroll ( hWnd, 
          LOWORD ( wParam ), 
          nScalarNum, 
          nScalarDen, 
          &rcView, 
          &nHScroll, 
          &nVScroll ) ; 
          break ; 
           
          case WM_VSCROLL: 
          OnVScroll ( hWnd, 
          LOWORD ( wParam ), 
          nScalarNum, 
          nScalarDen, 
          &rcView, 
          &nHScroll, 
          &nVScroll ) ; 
           
          break ; 
           
          case WM_PAINT: 
          OnPaint ( hWnd, &hBitmap, &rcView, hPalette ) ; 
          break ; 
           
          case WM_COMMAND: 
          switch( LOWORD( wParam ) ) 
          { 
             case ID_FILE_OPEN: 
             { 
                BITMAPHANDLE hTempBitmap ; 
                HDC hDC ; 
                 
                 
                if ( OnOpen ( hWnd, &hTempBitmap ) ) 
                { 
                   if ( hBitmap.Flags.Allocated ) 
                   { 
                      L_FreeBitmap  ( &hBitmap ) ; 
                   } 
                    
                   if ( hPalette ) 
                   { 
                      DeleteObject( hPalette ) ; 
                   } 
                   nScalarNum = 1 ; 
                   nScalarDen = 1 ; 
                   L_CopyBitmapHandle  (&hBitmap, &hTempBitmap , sizeof(BITMAPHANDLE)) ; 
                   hDC = GetDC ( hWnd ) ; 
                   hPalette = L_CreatePaintPalette  ( hDC, &hBitmap ) ; 
                   ReleaseDC ( hWnd, hDC ) ; 
                   {//ADJUST WINDOW SIZE 
                       
                      RECT  rcWindow ; 
                      L_INT nWidth, nHeight ; 
                       
                       
                      SystemParametersInfo ( SPI_GETWORKAREA, 0, &rcWindow, 0 ) ; 
                       
                      nWidth = min ( MulDiv ( BITMAPWIDTH ( &hBitmap ), nScalarNum, nScalarDen ), 
                      ( rcWindow.right  - rcWindow.left ) ) ; 
                       
                      nHeight = min ( MulDiv ( BITMAPHEIGHT ( &hBitmap ), nScalarNum, nScalarDen ), 
                      ( rcWindow.bottom - rcWindow.top  ) ) ; 
                       
                      MoveWindow ( hWnd, 
                      0, 
                      0, 
                      nWidth, 
                      nHeight, 
                      TRUE ) ; 
                       
                   }//ADJUST WINDOW SIZE 
                    
                   InvalidateRect ( hWnd, NULL, TRUE ) ; 
                } 
             } 
              
             return 0L ; 
              
             case IDM_EXIT: 
             PostMessage ( hWnd, WM_CLOSE, 0, 0 ) ; 
             return 0L ; 
          } 
           
          break ; 
       } 
        
       return DefWindowProc ( hWnd, uMessage, wParam, lParam ) ; 
    } 
  11. Replace the _tWinMain function with the following code:
    int APIENTRY _tWinMain(HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPTSTR    lpCmdLine, 
    int       nCmdShow) 
    { 
       const L_TCHAR szClassName [ ] = TEXT("lead_paint_automation_tutorial") ; 
       WNDCLASSEX WndClass ; 
       HWND hWnd ; 
       MSG Msg ; 
        
       UNREFERENCED_PARAMETER ( hPrevInstance ) ; 
       UNREFERENCED_PARAMETER ( lpCmdLine ) ; 
        
       // unlock lead file formats support 
       UNLOCKSUPPORT ( ) ; 
        
       WndClass.cbSize = sizeof ( WNDCLASSEX ) ; 
       WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; 
       WndClass.lpfnWndProc = WndProc ; 
       WndClass.cbClsExtra = 0 ; 
       WndClass.cbWndExtra = 0 ; 
       WndClass.hInstance = hInst ; 
       WndClass.hIcon = LoadIcon ( NULL, IDI_APPLICATION ) ; 
       WndClass.hCursor = LoadCursor ( NULL, IDC_ARROW ) ; 
       WndClass.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 ) ; 
       WndClass.lpszMenuName = MAKEINTRESOURCE ( IDC_TUTORIAL_AUTOMATION) ; 
       WndClass.lpszClassName = szClassName ; 
       WndClass.hIconSm = NULL ; 
        
       RegisterClassEx ( &WndClass ) ; 
        
       hWnd = CreateWindowEx ( 0L, 
       szClassName, 
       TEXT("Paint Automation Tutorial"), 
       WS_OVERLAPPEDWINDOW, 
       CW_USEDEFAULT, 
       0, 
       CW_USEDEFAULT, 
       0, 
       NULL, 
       NULL, 
       hInst, 
       NULL ) ; 
       ShowWindow ( hWnd, nCmdShow ) ; 
       UpdateWindow ( hWnd ) ; 
        
       while ( GetMessage ( &Msg, NULL, 0, 0 ) != 0 ) 
       { 
          TranslateMessage ( &Msg ) ; 
          DispatchMessage ( &Msg ) ; 
       } 
       UnregisterClass ( szClassName, hInst ) ; 
       return (L_INT)Msg.wParam ; 
    } 
  12. Add the following declaration to the WndProc function:
    static pAUTOMATIONHANDLE pAutomation ;  
  13. Replace the line "return 0L ;" after the statement "case WM_CREATE:" in the WndProc function with the following code:
    if ( SUCCESS == L_AutInit ( &pAutomation ) ) 
    { 
       // create the paint automation 
       if ( SUCCESS != L_AutCreate ( pAutomation, AUTOMATION_MODE_PAINT, 0 ) ) 
       { 
          MessageBox ( hWnd, TEXT("Error creating Paint Automation"), TEXT("Error:"), MB_ICONSTOP ); 
          L_AutFree (pAutomation ) ; 
          return -1 ; 
       } 
       return 0L ; 
    } 
    else 
    { 
       return -1L ; 
    } 
  14. Add the following lines to the WndProc function before the statement "PostQuitMessage" in the "case WM_DESTROY:"
    if ( SUCCESS == L_AutIsValid ( pAutomation ) ) 
    { 
       L_AutFree ( pAutomation ) ; 
    } 
  15. Compile and run the project by selecting Build->Execute tutorial.exe from the menu.
Help Version 20.0.2020.4.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2020 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Container and Automation C API Help