// MFCWarpDlg.cpp : implementation file // #include "stdafx.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAPIWarpDlg dialog CAPIWarpDlg::CAPIWarpDlg(CWnd* pParent /*=NULL*/) : CDialog(CAPIWarpDlg::IDD, pParent) { //{{AFX_DATA_INIT(CAPIWarpDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CAPIWarpDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAPIWarpDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAPIWarpDlg, CDialog) //{{AFX_MSG_MAP(CAPIWarpDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_COMBINE, OnButtonCombine) ON_BN_CLICKED(IDC_CHECK_SHOW_OUTLINE, OnCheckShowOutline) ON_BN_CLICKED(IDC_BUTTON_LOAD_SLAVE, OnButtonLoadSlave) ON_BN_CLICKED(IDC_CHECK_BILINEAR_INTERPOLATE, OnCheckBilinearInterpolate) ON_WM_DESTROY() ON_BN_CLICKED(IDC_BUTTON_LOAD_MASTER, OnButtonLoadMaster) ON_BN_CLICKED(IDC_CHECK_RESAMPLE_DISPLAY, OnCheckResampleDisplay) ON_BN_CLICKED(IDC_MASTER_FIT_IMAGE, OnMasterFitImage) ON_BN_CLICKED(IDC_SLAVE_FIT_IMAGE, OnSlaveFitImage) ON_BN_CLICKED(IDC_MASTER_NORMALSIZE, OnMasterNormalsize) ON_BN_CLICKED(IDC_SLAVE_NORMALSIZE, OnSlaveNormalsize) ON_WM_QUERYNEWPALETTE() ON_WM_PALETTECHANGED() ON_BN_CLICKED(IDC_ZOOMIN, OnZoomin) ON_BN_CLICKED(IDC_ZOOMOUT, OnZoomout) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAPIWarpDlg message handlers BOOL CAPIWarpDlg::OnInitDialog() { CDialog::OnInitDialog(); CWnd *pWnd = NULL; // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon m_hAnnPolygon = NULL; m_hContainer = NULL; // Create the Master Window CreateMasterWindow(); // Create the Slave Window CreateSlaveWindow(); m_Points[0].x = 25; m_Points[0].y = 25; m_Points[1].x = 100; m_Points[1].y = 25; m_Points[2].x = 100; m_Points[2].y = 100; m_Points[3].x = 25; m_Points[3].y = 100; // TODO: Add extra initialization here m_hMasterPalette = NULL; m_hSlavePalette = NULL; m_hContainer = NULL; m_bMasterInScroll = FALSE; m_bSlaveInScroll = FALSE; // Initialize the scroll values m_nMasterVscrollMax = 0; m_nMasterVscrollPos = 0; m_nMasterVscrollStep = 0; m_nSlaveVscrollMax = 0; m_nSlaveVscrollPos = 0; m_nSlaveVscrollStep = 0; m_nMasterHscrollMax = 0; m_nMasterHscrollPos = 0; m_nMasterHscrollStep = 0; m_nSlaveHscrollMax = 0; m_nSlaveHscrollPos = 0; m_nSlaveHscrollStep = 0; L_InitBitmap(&m_MasterBitmap, sizeof(BITMAPHANDLE), 0, 0, 0); L_InitBitmap(&m_SlaveBitmap, sizeof(BITMAPHANDLE), 0, 0, 0); UNLOCKSUPPORT(); L_LoadBitmap(TEXT("Master.jpg"), &m_MasterBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, NULL, NULL); L_LoadBitmap(TEXT("Slave.jpg"), &m_SlaveBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, NULL, NULL); CButton *pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_SHOW_OUTLINE); pCheckBox->SetCheck(TRUE); OnCheckShowOutline(); pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_RESAMPLE_DISPLAY); pCheckBox->SetCheck(TRUE); pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_BILINEAR_INTERPOLATE); pCheckBox->SetCheck(TRUE); // Initialize checkboxes OnCheckBilinearInterpolate(); OnCheckResampleDisplay(); // Create the annotation polygon CreateNewPolygon(); // Fit the Images OnMasterFitImage(); OnSlaveFitImage(); if ((!m_MasterBitmap.Flags.Allocated) || (!m_SlaveBitmap.Flags.Allocated)) { // Disable the combine button GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(FALSE); } if (!m_MasterBitmap.Flags.Allocated) { GetDlgItem(IDC_MASTER_NORMALSIZE)->EnableWindow(FALSE); GetDlgItem(IDC_MASTER_FIT_IMAGE)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_RESAMPLE_DISPLAY)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_SHOW_OUTLINE)->EnableWindow(FALSE); GetDlgItem(IDC_ZOOMIN)->EnableWindow(FALSE); GetDlgItem(IDC_ZOOMOUT)->EnableWindow(FALSE); } if (!m_SlaveBitmap.Flags.Allocated) { GetDlgItem(IDC_SLAVE_NORMALSIZE)->EnableWindow(FALSE); GetDlgItem(IDC_SLAVE_FIT_IMAGE)->EnableWindow(FALSE); } return TRUE; // return TRUE unless you set the focus to a control } L_VOID CAPIWarpDlg::CreateMasterWindow() { static TCHAR szMasterClass[] = TEXT("MASTERCLASS"); WNDCLASS wndclass; RECT rcMaster; // Register the frame window class wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = MasterWndProcS; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = AfxGetInstanceHandle(); wndclass.hIcon = LoadIcon (AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szMasterClass; if (!RegisterClass (&wndclass)) return; m_hWndMaster = CreateWindow(szMasterClass, TEXT(""), WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, GetSafeHwnd(), NULL, AfxGetInstanceHandle(), (LPVOID)this); GetDlgItem(IDC_STATIC_MASTER)->GetWindowRect(&rcMaster); ScreenToClient(&rcMaster); ::MoveWindow(m_hWndMaster, rcMaster.left, rcMaster.top, rcMaster.right - rcMaster.left, rcMaster.bottom - rcMaster.top, TRUE); ::ShowWindow(m_hWndMaster, SW_SHOW); ::UpdateWindow(m_hWndMaster); } LRESULT CALLBACK CAPIWarpDlg::MasterWndProcS(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { CAPIWarpDlg *pDlg = NULL; if(message == WM_CREATE) pDlg = (CAPIWarpDlg* )(((LPCREATESTRUCT)lParam)->lpCreateParams); else pDlg = (CAPIWarpDlg*)GetProp(hwnd, PROP_MASTER); return pDlg->MasterWndProc(hwnd, message, wParam, lParam); return ::DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK CAPIWarpDlg::MasterWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HPALETTE OldPalette = NULL; switch (message) { case WM_CREATE: ::SetProp(hwnd, PROP_MASTER, this); ::SetScrollRange(hwnd,SB_VERT,0,0,FALSE); ::SetScrollRange(hwnd,SB_HORZ,0,0,FALSE); return 0; case WM_PAINT: ::BeginPaint(hwnd, &ps); if (m_hMasterPalette) { OldPalette = ::SelectPalette(ps.hdc, m_hMasterPalette, TRUE); RealizePalette(ps.hdc); } if (m_MasterBitmap.Flags.Allocated) L_PaintDC(ps.hdc, &m_MasterBitmap, NULL, NULL, &m_rcDstMaster, &ps.rcPaint, SRCCOPY); if (m_hContainer) L_AnnDraw(ps.hdc, &ps.rcPaint, m_hContainer); if (OldPalette) DeleteObject(OldPalette); ::EndPaint(hwnd, &ps); return 0; case WM_SIZE: if (m_hContainer) { L_AnnSetOffsetX(m_hContainer, (L_DOUBLE) m_rcDstMaster.left, ANNFLAG_NOINVALIDATE); L_AnnSetOffsetY(m_hContainer, (L_DOUBLE) m_rcDstMaster.top, ANNFLAG_NOINVALIDATE); L_AnnSetScalarX(m_hContainer, (L_DOUBLE) RECTWIDTH(&m_rcDstMaster) / BITMAPWIDTH(&m_MasterBitmap), ANNFLAG_NOINVALIDATE); L_AnnSetScalarY(m_hContainer, (L_DOUBLE) RECTHEIGHT(&m_rcDstMaster) / BITMAPHEIGHT(&m_MasterBitmap), ANNFLAG_NOINVALIDATE); } return 0; case WM_VSCROLL: OnMasterVScroll(LOWORD(wParam), HIWORD(wParam)); return 0; case WM_HSCROLL: OnMasterHScroll(LOWORD(wParam), HIWORD(wParam)); return 0; case WM_ERASEBKGND: OnMasterEraseBkgnd((HDC)wParam); return 0; case WM_DESTROY: RemoveProp(hwnd, PROP_MASTER); PostQuitMessage(0); return 0; } return ::DefWindowProc(hwnd, message, wParam, lParam); } L_VOID CAPIWarpDlg::CreateSlaveWindow() { static TCHAR szSlaveClass[] = TEXT("SlaveCLASS"); WNDCLASS wndclass; RECT rcSlave; // Register the frame window class wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = SlaveWndProcS; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = AfxGetInstanceHandle(); wndclass.hIcon = LoadIcon (AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szSlaveClass; if (!RegisterClass (&wndclass)) return; m_hWndSlave = CreateWindow(szSlaveClass, TEXT(""), WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, GetSafeHwnd(), NULL, AfxGetInstanceHandle(), (LPVOID)this); GetDlgItem(IDC_STATIC_SLAVE)->GetWindowRect(&rcSlave); ScreenToClient(&rcSlave); ::MoveWindow(m_hWndSlave, rcSlave.left, rcSlave.top, rcSlave.right - rcSlave.left, rcSlave.bottom - rcSlave.top, TRUE); ::ShowWindow(m_hWndSlave, SW_SHOW); ::UpdateWindow(m_hWndSlave); } LRESULT CALLBACK CAPIWarpDlg::SlaveWndProcS(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { CAPIWarpDlg *pDlg = NULL; if(message == WM_CREATE) pDlg = (CAPIWarpDlg* )(((LPCREATESTRUCT)lParam)->lpCreateParams); else pDlg = (CAPIWarpDlg*)GetProp(hwnd, PROP_SLAVE); return pDlg->SlaveWndProc(hwnd, message, wParam, lParam); return ::DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK CAPIWarpDlg::SlaveWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HPALETTE OldPalette = NULL; switch (message) { case WM_CREATE: ::SetProp(hwnd, PROP_SLAVE, this); ::SetScrollRange(hwnd,SB_VERT,0,0,FALSE); ::SetScrollRange(hwnd,SB_HORZ,0,0,FALSE); return 0; case WM_PAINT: ::BeginPaint(hwnd, &ps); if (m_hSlavePalette) { OldPalette = ::SelectPalette(ps.hdc, m_hSlavePalette, TRUE); RealizePalette(ps.hdc); } if (m_SlaveBitmap.Flags.Allocated) L_PaintDC(ps.hdc, &m_SlaveBitmap, NULL, NULL, &m_rcDstSlave, &ps.rcPaint, SRCCOPY); if (OldPalette) DeleteObject(OldPalette); ::EndPaint(hwnd, &ps); return 0; case WM_VSCROLL: OnSlaveVScroll(LOWORD(wParam), HIWORD(wParam)); return 0; case WM_HSCROLL: OnSlaveHScroll(LOWORD(wParam), HIWORD(wParam)); return 0; case WM_ERASEBKGND: OnSlaveEraseBkgnd((HDC)wParam); return 0; case WM_DESTROY: RemoveProp(hwnd, PROP_SLAVE); PostQuitMessage(0); return 0; } return ::DefWindowProc(hwnd, message, wParam, lParam); } L_FLOAT CAPIWarpDlg::MatchAspectRatioSize(LPRECT pRect, L_INT nWidth, L_INT nHeight, HWND hWnd) { L_INT cxRect, cyRect; L_FLOAT fZoomFactor; L_INT nDx, nDy; nDx = pRect->right; nDy = pRect->bottom; cyRect = pRect->bottom - pRect->top; cxRect = MulDiv(cyRect,nWidth,nHeight); fZoomFactor = (L_FLOAT)cyRect / (L_FLOAT)nHeight; if(cxRect>(pRect->right - pRect->left)) { cxRect=(pRect->right - pRect->left); cyRect=MulDiv(cxRect,nHeight,nWidth); fZoomFactor = (L_FLOAT)cxRect / (L_FLOAT)nWidth; } pRect->bottom = pRect->top + cyRect; pRect->right = pRect->left + cxRect; // Make the bitmap in center CenterBitmap(pRect, hWnd); return fZoomFactor; } L_VOID CAPIWarpDlg::CenterBitmap(RECT* pRect, HWND hWnd) { RECT rect; L_INT nVScroll, nHScroll; DWORD dwStyle; ::GetClientRect(hWnd, &rect); nVScroll = GetSystemMetrics (SM_CXVSCROLL) - GetSystemMetrics(SM_CXBORDER); nHScroll = GetSystemMetrics (SM_CYHSCROLL) - GetSystemMetrics(SM_CYBORDER); dwStyle = GetWindowLong (hWnd, GWL_STYLE); if (WS_VSCROLL & dwStyle) rect.bottom += (nVScroll + 1); if (WS_HSCROLL & dwStyle) rect.right += (nHScroll + 1); L_INT nWidth =pRect->right-pRect->left; L_INT nHeight=pRect->bottom-pRect->top; if(nWidth>rect.right) { if(pRect->left>0) { pRect->right-=pRect->left; pRect->left=0; } else if(pRect->rightleft-=(pRect->right-rect.right); pRect->right=rect.right; } } else { pRect->left = (rect.right-nWidth)>>1; pRect->right = pRect->left+nWidth; } if(nHeight>rect.bottom) { if(pRect->top>0) { pRect->bottom-=pRect->top; pRect->top=0; } else if(pRect->bottomtop -=(pRect->bottom-rect.bottom); pRect->bottom= rect.bottom; } } else { pRect->top = (rect.bottom-nHeight)>>1; pRect->bottom= pRect->top +nHeight; } } void CAPIWarpDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CAPIWarpDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle L_INT cxIcon = GetSystemMetrics(SM_CXICON); L_INT cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); L_INT x = (rect.Width() - cxIcon + 1) / 2; L_INT y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CAPIWarpDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CAPIWarpDlg::OnButtonCombine() { ANNPOINT AnnPoints[4] = {0,0,0,0,0,0,0,0}; CString strMsg=""; CString strTmp; L_INT nRet, nWidth, nHeight; if (IsDlgButtonChecked(IDC_MASTER_NORMALSIZE)) { nWidth = BITMAPWIDTH(&m_MasterBitmap); nHeight = BITMAPHEIGHT(&m_MasterBitmap); } else { nWidth = (m_rcDstMaster.right - m_rcDstMaster.left); nHeight =(m_rcDstMaster.bottom - m_rcDstMaster.top); } L_AnnGetPoints(m_hAnnPolygon, AnnPoints); POINT ptDstArray[4]; for (L_INT i=0; i<4; i++) { ptDstArray[i].x = (LONG)AnnPoints[i].x; ptDstArray[i].y = (LONG)AnnPoints[i].y; } // Note that the bits per pixel of master and slave must be the same // If palettized, the palettes must be the same L_UINT uMasterBPP = m_MasterBitmap.BitsPerPixel; L_UINT uSlaveBPP = m_SlaveBitmap.BitsPerPixel; if ((uMasterBPP < 24) || (uSlaveBPP < 24)) { L_UINT uBitsPerPixel = max(uMasterBPP, uSlaveBPP ); if (uMasterBPP != uBitsPerPixel) L_ColorResBitmap(&m_MasterBitmap, &m_MasterBitmap, sizeof(BITMAPHANDLE), uBitsPerPixel, CRF_FIXEDPALETTE | CRF_BYTEORDERBGR, NULL, NULL, 0, NULL, NULL); if (uSlaveBPP != uBitsPerPixel) L_ColorResBitmap(&m_SlaveBitmap, &m_SlaveBitmap, sizeof(BITMAPHANDLE), uBitsPerPixel, CRF_FIXEDPALETTE | CRF_BYTEORDERBGR, NULL, NULL, 0, NULL, NULL); } POINT ptSrc = {0,0}; L_UINT uFlags = m_bBilinearInterpolate ? CBW_BILINEAR : 0; BeginWaitCursor(); nRet = L_CombineBitmapWarp(&m_MasterBitmap, ptDstArray, &m_SlaveBitmap, ptSrc, m_SlaveBitmap.Width, m_SlaveBitmap.Height, uFlags); EndWaitCursor(); if (nRet == ERROR_FEATURE_NOT_SUPPORTED) { MessageBox(TEXT("Error--Feature not supported")); } else if (nRet != SUCCESS) { TCHAR *pszMsg = TEXT("One of the following caused the error:\n") TEXT("1. Polygon must be concave\n") TEXT("2. Polygon must lie completely on the master bitmap\n") TEXT("3. The bits per pixel of the Master and Slave must be the same\n") TEXT("4. Master or slave image not loaded\n"); MessageBox(pszMsg); } else { ::InvalidateRect(m_hWndMaster, NULL, FALSE); ::UpdateWindow(m_hWndMaster); } } void CAPIWarpDlg::OnCheckShowOutline() { CButton *pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_SHOW_OUTLINE); L_INT nVisible = pCheckBox->GetCheck(); if (m_hContainer) { L_AnnSetVisible(m_hContainer, nVisible, ANNFLAG_RECURSE, NULL); L_AnnSetSelected(m_hContainer, nVisible, ANNFLAG_RECURSE | ANNFLAG_NOTCONTAINER); L_AnnSetSelected(m_hContainer, TRUE, ANNFLAG_RECURSE | ANNFLAG_NOTCONTAINER); } Invalidate(FALSE); } void CAPIWarpDlg::OnButtonLoadSlave() { HCURSOR hOldCur; OPENFILENAME OpenFileName; LOADFILEOPTION LoadFileOpt; L_TCHAR szFile[MAX_PATH]; L_TCHAR szOpenFileFilter[] = TEXT("ALL\0")TEXT("*.*\0"); L_INT nRet, nPage = 0; memset(szFile, 0, MAX_PATH); OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.hwndOwner = m_hWnd; OpenFileName.lpstrFilter = szOpenFileFilter; OpenFileName.lpstrCustomFilter = NULL; OpenFileName.nMaxCustFilter = 0; OpenFileName.nFilterIndex = 1; OpenFileName.lpstrFile = szFile; OpenFileName.nMaxFile = sizeof(szFile)/sizeof(L_TCHAR);; OpenFileName.lpstrFileTitle = NULL; OpenFileName.nMaxFileTitle = 0; OpenFileName.lpstrInitialDir = NULL; OpenFileName.lpstrTitle = TEXT("Open Slave Bitmap"); OpenFileName.nFileOffset = 0; OpenFileName.nFileExtension = 0; OpenFileName.lpstrDefExt = NULL; OpenFileName.lpfnHook = NULL; OpenFileName.Flags = 0; if (!m_SlaveBitmap.Flags.Allocated) L_InitBitmap(&m_SlaveBitmap, sizeof(BITMAPHANDLE), 0, 0, 0); if (GetOpenFileName(&OpenFileName)) { hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); L_GetDefaultLoadFileOption(&LoadFileOpt, sizeof(LoadFileOpt)); LoadFileOpt.PageNumber = 1; BeginWaitCursor(); nRet = L_LoadBitmap(szFile, &m_SlaveBitmap, sizeof(BITMAPHANDLE), 24, ORDER_BGRORGRAY, &LoadFileOpt, NULL); EndWaitCursor(); if(nRet != SUCCESS ) if(nRet == ERROR_PDF_BAD_INITIALIZATION_FILES) { if( IDYES == MessageBox( TEXT("LEADTOOLS PDF plugin is not found, do you want to download the plugin now?"), TEXT("Open file"),MB_ICONEXCLAMATION | MB_YESNO)) ShellExecute(m_hWnd, TEXT("open"), TEXT("http://www.leadtools.com/ReleaseDownloads/v14/LEADTOOLSPDFRuntime.exe"), NULL, NULL, SW_SHOWNORMAL); } else MessageBox(TEXT("Error loading bitmap"), TEXT("Error")); if (!m_SlaveBitmap.Flags.Allocated) { GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(FALSE); GetDlgItem(IDC_SLAVE_NORMALSIZE)->EnableWindow(FALSE); GetDlgItem(IDC_SLAVE_FIT_IMAGE)->EnableWindow(FALSE); return; } else { if (m_MasterBitmap.Flags.Allocated) GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(TRUE); else GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(FALSE); GetDlgItem(IDC_SLAVE_NORMALSIZE)->EnableWindow(TRUE); GetDlgItem(IDC_SLAVE_FIT_IMAGE)->EnableWindow(TRUE); OnSlaveFitImage(); // Change the View Perspective if(m_SlaveBitmap.ViewPerspective != TOP_LEFT) L_ChangeBitmapViewPerspective(NULL, &m_SlaveBitmap, sizeof(BITMAPHANDLE), TOP_LEFT); } SetCursor(hOldCur); OnQueryNewPalette(); } } void CAPIWarpDlg::OnCheckBilinearInterpolate() { CButton *pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_BILINEAR_INTERPOLATE); m_bBilinearInterpolate = pCheckBox->GetCheck(); } void CAPIWarpDlg::OnDestroy() { CDialog::OnDestroy(); if (m_hMasterPalette) DeleteObject(m_hMasterPalette); if (m_hSlavePalette) DeleteObject(m_hSlavePalette); if (m_hAnnPolygon) L_AnnDestroy(m_hAnnPolygon, 0); if(m_hAutomation) { L_AnnSetActiveState(m_hAutomation, ANNACTIVE_DISABLED); L_AnnDestroy(m_hAutomation, ANNFLAG_NOINVALIDATE); } if(m_hContainer) L_AnnDestroy(m_hContainer, ANNFLAG_NOINVALIDATE); if (m_MasterBitmap.Flags.Allocated) L_FreeBitmap(&m_MasterBitmap); if (m_SlaveBitmap.Flags.Allocated) L_FreeBitmap(&m_SlaveBitmap); } void CAPIWarpDlg::OnButtonLoadMaster() { HCURSOR hOldCur; OPENFILENAME OpenFileName; LOADFILEOPTION LoadFileOpt; L_TCHAR szFile[MAX_PATH]; L_TCHAR szOpenFileFilter[] = TEXT("ALL\0")TEXT("*.*\0"); L_INT nRet, nPage = 0; memset(szFile, 0, MAX_PATH); OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.hwndOwner = m_hWnd; OpenFileName.lpstrFilter = szOpenFileFilter; OpenFileName.lpstrCustomFilter = NULL; OpenFileName.nMaxCustFilter = 0; OpenFileName.nFilterIndex = 1; OpenFileName.lpstrFile = szFile; OpenFileName.nMaxFile = sizeof(szFile)/sizeof(L_TCHAR);; OpenFileName.lpstrFileTitle = NULL; OpenFileName.nMaxFileTitle = 0; OpenFileName.lpstrInitialDir = NULL; OpenFileName.lpstrTitle = TEXT("Open Master Bitmap"); OpenFileName.nFileOffset = 0; OpenFileName.nFileExtension = 0; OpenFileName.lpstrDefExt = NULL; OpenFileName.lpfnHook = NULL; OpenFileName.Flags = 0; if (!m_MasterBitmap.Flags.Allocated) L_InitBitmap(&m_MasterBitmap, sizeof(BITMAPHANDLE), 0, 0, 0); if (GetOpenFileName(&OpenFileName)) { hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT)); L_GetDefaultLoadFileOption(&LoadFileOpt, sizeof(LoadFileOpt)); LoadFileOpt.PageNumber = 1; BeginWaitCursor(); nRet = L_LoadBitmap(szFile, &m_MasterBitmap, sizeof(BITMAPHANDLE), 24, ORDER_BGRORGRAY, &LoadFileOpt, NULL); EndWaitCursor(); if(nRet != SUCCESS) if(nRet == ERROR_PDF_BAD_INITIALIZATION_FILES) { if( IDYES == MessageBox( TEXT("LEADTOOLS PDF plugin is not found, do you want to download the plugin now?"), TEXT("Open file"),MB_ICONEXCLAMATION | MB_YESNO)) ShellExecute(m_hWnd, TEXT("open"), TEXT("http://www.leadtools.com/ReleaseDownloads/v14/LEADTOOLSPDFRuntime.exe"), NULL, NULL, SW_SHOWNORMAL); } else MessageBox(TEXT("Error loading bitmap"), TEXT("Error")); if (!m_MasterBitmap.Flags.Allocated) { GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(FALSE); GetDlgItem(IDC_MASTER_NORMALSIZE)->EnableWindow(FALSE); GetDlgItem(IDC_MASTER_FIT_IMAGE)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_RESAMPLE_DISPLAY)->EnableWindow(FALSE); GetDlgItem(IDC_CHECK_SHOW_OUTLINE)->EnableWindow(FALSE); GetDlgItem(IDC_ZOOMIN)->EnableWindow(FALSE); GetDlgItem(IDC_ZOOMOUT)->EnableWindow(FALSE); return; } else { if (m_SlaveBitmap.Flags.Allocated) GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(TRUE); else GetDlgItem(IDC_BUTTON_COMBINE)->EnableWindow(FALSE); GetDlgItem(IDC_MASTER_NORMALSIZE)->EnableWindow(TRUE); GetDlgItem(IDC_MASTER_FIT_IMAGE)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK_RESAMPLE_DISPLAY)->EnableWindow(TRUE); GetDlgItem(IDC_CHECK_SHOW_OUTLINE)->EnableWindow(TRUE); GetDlgItem(IDC_ZOOMIN)->EnableWindow(TRUE); GetDlgItem(IDC_ZOOMOUT)->EnableWindow(TRUE); // Change the View Perspective if(m_MasterBitmap.ViewPerspective != TOP_LEFT) L_ChangeBitmapViewPerspective(NULL, &m_MasterBitmap, sizeof(BITMAPHANDLE), TOP_LEFT); // Update the annotation rectangle ANNRECT newRect; newRect.left = 0; newRect.top = 0; newRect.right = BITMAPWIDTH(&m_MasterBitmap); newRect.bottom = BITMAPHEIGHT(&m_MasterBitmap); L_AnnSetRect(m_hContainer, &newRect); OnMasterFitImage(); SetPolygonPoints(); } SetCursor(hOldCur); OnQueryNewPalette(); } } void CAPIWarpDlg::CreateNewPolygon() { //Delete old annotation object if (m_hAnnPolygon) L_AnnDestroy(m_hAnnPolygon, 0); //If the loaded bitmap is really small, make sure the polygon fits ANNRECT AnnRect ; AnnRect.left = 0; AnnRect.top = 0; AnnRect.right = BITMAPWIDTH(&m_MasterBitmap); AnnRect.bottom = BITMAPHEIGHT(&m_MasterBitmap); L_AnnCreateContainer(m_hWndMaster, &AnnRect, TRUE, &m_hContainer) ; L_AnnSetUserMode(m_hContainer, ANNUSER_DESIGN); L_AnnCreate(ANNOBJECT_AUTOMATION, &m_hAutomation); L_AnnSetAutoContainer(m_hAutomation, m_hContainer); L_AnnSetActiveState(m_hAutomation, ANNACTIVE_ENABLED); L_AnnSetAutoMenuEnable(m_hAutomation, FALSE); /* Create the automation object */ L_AnnCreate(ANNOBJECT_POLYGON, &m_hAnnPolygon); L_AnnInsert(m_hContainer, m_hAnnPolygon, FALSE); SetPolygonPoints(); L_AnnSetVisible(m_hAnnPolygon, TRUE, 0, NULL); L_AnnSetForeColor(m_hAnnPolygon, RGB(255,0,0), 0); L_AnnSetSelected(m_hAnnPolygon, TRUE, ANNFLAG_RECURSE); L_AnnSetAutoContainer(m_hAnnPolygon, m_hContainer); L_AnnSetActiveState(m_hAnnPolygon, ANNACTIVE_ENABLED); L_AnnSetDpiX(m_hAnnPolygon, 600, 0); L_AnnSetDpiY(m_hAnnPolygon, 600, 0); } void CAPIWarpDlg::SetPolygonPoints() { L_AnnSetPoints(m_hAnnPolygon, m_Points, 4); } void CAPIWarpDlg::OnCheckResampleDisplay() { CButton *pCheckBox; L_INT bResampleDisplay; pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_RESAMPLE_DISPLAY); bResampleDisplay = pCheckBox->GetCheck(); if (bResampleDisplay) L_SetDisplayMode(DISPLAYMODE_RESAMPLE, DISPLAYMODE_RESAMPLE); else L_SetDisplayMode(DISPLAYMODE_RESAMPLE, 0); Invalidate(FALSE); } void CAPIWarpDlg::OnMasterFitImage() { m_nMasterHscrollPos = 0; m_nMasterVscrollPos = 0; CheckDlgButton(IDC_MASTER_FIT_IMAGE, 1); CheckDlgButton(IDC_MASTER_NORMALSIZE, 0); ::GetClientRect(m_hWndMaster, &m_rcDstMaster); m_nZoomFactor = 100; // Update master scroll bars UpdateMasterScrollBar(TRUE); // Update polygon scale UpdatePolygonScale(); ::InvalidateRect(m_hWndMaster, NULL, TRUE); ::UpdateWindow(m_hWndMaster); } void CAPIWarpDlg::OnMasterNormalsize() { CheckDlgButton(IDC_MASTER_NORMALSIZE, 1); CheckDlgButton(IDC_MASTER_FIT_IMAGE, 0); m_nZoomFactor = 100; // Update master scroll bars UpdateMasterScrollBar(FALSE); // Make the bitmap in center CenterBitmap(&m_rcDstMaster, m_hWndMaster); // Update polygon scale UpdatePolygonScale(); ::InvalidateRect(m_hWndMaster, NULL, TRUE); ::UpdateWindow(m_hWndMaster); } L_VOID CAPIWarpDlg::UpdateMasterScrollBar(L_BOOL bFitImage) { L_INT nWidth, nHeight, nVScroll, nHScroll; L_INT cxClient, cyClient; DWORD dwStyle; RECT rcClient; ::GetClientRect (m_hWndMaster, &rcClient); if (IsDlgButtonChecked(IDC_MASTER_FIT_IMAGE)) { nWidth = 0; nHeight = 0; } else { nWidth = MulDiv (BITMAPWIDTH(&m_MasterBitmap), m_nZoomFactor, 100); nHeight = MulDiv (BITMAPHEIGHT(&m_MasterBitmap), m_nZoomFactor, 100); } nVScroll = GetSystemMetrics (SM_CXVSCROLL) - GetSystemMetrics(SM_CXBORDER); nHScroll = GetSystemMetrics (SM_CYHSCROLL) - GetSystemMetrics(SM_CYBORDER); cxClient = RECTWIDTH(&rcClient); cyClient = RECTHEIGHT(&rcClient); dwStyle = GetWindowLong (m_hWndMaster, GWL_STYLE); if (WS_VSCROLL & dwStyle) cxClient += (nVScroll + 1); if (WS_HSCROLL & dwStyle) cyClient += (nHScroll + 1); if (cxClient < nWidth) { cyClient -= nHScroll; if (cyClient < nHeight) cxClient -= nVScroll; } else if (cyClient < nHeight) { cxClient -= nVScroll; if (cxClient < nWidth) cyClient -= nHScroll; } m_nMasterHscrollStep = max (1, cxClient / 10); m_nMasterVscrollStep = max (1, cyClient / 10); m_nMasterVscrollMax = max (0, (nHeight - cyClient)); m_nMasterVscrollPos = max (0, min (m_nMasterVscrollPos, m_nMasterVscrollMax)); m_nMasterHscrollMax = max (0, (nWidth - cxClient)); m_nMasterHscrollPos = max (0, min (m_nMasterHscrollPos, m_nMasterHscrollMax)); if (bFitImage) { SetRect (&m_rcDstMaster, 0, 0, cxClient, cyClient); m_nZoomFactor = (L_INT)(MatchAspectRatioSize(&m_rcDstMaster, BITMAPWIDTH(&m_MasterBitmap), BITMAPHEIGHT(&m_MasterBitmap), m_hWndMaster) * 100.0f); } else { SetRect (&m_rcDstMaster, 0, 0, nWidth, nHeight); OffsetRect (&m_rcDstMaster, -m_nMasterHscrollPos, -m_nMasterVscrollPos); } ::SetScrollRange(m_hWndMaster, SB_HORZ, 0, m_nMasterHscrollMax, FALSE); ::SetScrollPos(m_hWndMaster, SB_HORZ, m_nMasterHscrollPos, TRUE); ::SetScrollRange(m_hWndMaster, SB_VERT, 0, m_nMasterVscrollMax, FALSE); ::SetScrollPos(m_hWndMaster, SB_VERT, m_nMasterVscrollPos, TRUE); } L_VOID CAPIWarpDlg::UpdateSlaveScrollBar(L_BOOL bFitImage) { L_INT nWidth, nHeight, nVScroll, nHScroll; L_INT cxClient, cyClient; DWORD dwStyle; RECT rcClient; ::GetClientRect (m_hWndSlave, &rcClient); if (IsDlgButtonChecked(IDC_SLAVE_FIT_IMAGE)) { nWidth = 0; nHeight = 0; } else { nWidth = BITMAPWIDTH(&m_SlaveBitmap); nHeight = BITMAPHEIGHT(&m_SlaveBitmap); } nVScroll = GetSystemMetrics (SM_CXVSCROLL) - GetSystemMetrics(SM_CXBORDER); nHScroll = GetSystemMetrics (SM_CYHSCROLL) - GetSystemMetrics(SM_CYBORDER); cxClient = RECTWIDTH(&rcClient); cyClient = RECTHEIGHT(&rcClient); dwStyle = GetWindowLong (m_hWndSlave, GWL_STYLE); if (WS_VSCROLL & dwStyle) cxClient += (nVScroll + 1); if (WS_HSCROLL & dwStyle) cyClient += (nHScroll + 1); if (cxClient < nWidth) { cyClient -= nHScroll; if (cyClient < nHeight) cxClient -= nVScroll; } else if (cyClient < nHeight) { cxClient -= nVScroll; if (cxClient < nWidth) cyClient -= nHScroll; } m_nSlaveHscrollStep = max (1, cxClient / 10); m_nSlaveVscrollStep = max (1, cyClient / 10); m_nSlaveVscrollMax = max (0, (nHeight - cyClient)); m_nSlaveVscrollPos = max (0, min (m_nSlaveVscrollPos, m_nSlaveVscrollMax)); m_nSlaveHscrollMax = max (0, (nWidth - cxClient)); m_nSlaveHscrollPos = max (0, min (m_nSlaveHscrollPos, m_nSlaveHscrollMax)); if (bFitImage) { SetRect (&m_rcDstSlave, 0, 0, cxClient, cyClient); MatchAspectRatioSize(&m_rcDstSlave, BITMAPWIDTH(&m_SlaveBitmap), BITMAPHEIGHT(&m_SlaveBitmap), m_hWndSlave); } else { SetRect (&m_rcDstSlave, 0, 0, nWidth, nHeight); OffsetRect (&m_rcDstSlave, -m_nSlaveHscrollPos, -m_nSlaveVscrollPos); } ::SetScrollRange(m_hWndSlave, SB_HORZ, 0, m_nSlaveHscrollMax, FALSE); ::SetScrollPos(m_hWndSlave, SB_HORZ, m_nSlaveHscrollPos, TRUE); ::SetScrollRange(m_hWndSlave, SB_VERT, 0, m_nSlaveVscrollMax, FALSE); ::SetScrollPos(m_hWndSlave, SB_VERT, m_nSlaveVscrollPos, TRUE); } L_VOID CAPIWarpDlg::UpdatePolygonScale() { if (m_hContainer) { L_AnnSetOffsetX(m_hContainer, (L_DOUBLE) m_rcDstMaster.left, ANNFLAG_NOINVALIDATE); L_AnnSetOffsetY(m_hContainer, (L_DOUBLE) m_rcDstMaster.top, ANNFLAG_NOINVALIDATE); L_AnnSetScalarX(m_hContainer, (L_DOUBLE) RECTWIDTH(&m_rcDstMaster) / BITMAPWIDTH(&m_MasterBitmap), ANNFLAG_NOINVALIDATE); L_AnnSetScalarY(m_hContainer, (L_DOUBLE) RECTHEIGHT(&m_rcDstMaster) / BITMAPHEIGHT(&m_MasterBitmap), ANNFLAG_NOINVALIDATE); } } void CAPIWarpDlg::OnSlaveFitImage() { m_nSlaveHscrollPos = 0; m_nSlaveVscrollPos = 0; CheckDlgButton(IDC_SLAVE_FIT_IMAGE, 1); CheckDlgButton(IDC_SLAVE_NORMALSIZE, 0); // Update Slave scroll bars UpdateSlaveScrollBar(TRUE); ::InvalidateRect(m_hWndSlave, NULL, TRUE); ::UpdateWindow(m_hWndSlave); } void CAPIWarpDlg::OnSlaveNormalsize() { CheckDlgButton(IDC_SLAVE_NORMALSIZE, 1); CheckDlgButton(IDC_SLAVE_FIT_IMAGE, 0); // Update Slave scroll bars UpdateSlaveScrollBar(FALSE); // Make the bitmap in center CenterBitmap(&m_rcDstSlave, m_hWndSlave); ::InvalidateRect(m_hWndSlave, NULL, TRUE); ::UpdateWindow(m_hWndSlave); } L_BOOL CAPIWarpDlg::OnMasterEraseBkgnd(HDC hDC) { HBRUSH hBrush; HRGN hClientRgn, hFillRgn; RECT rcView, rcClient; hBrush = (HBRUSH)GetClassLong(m_hWndMaster, GCL_HBRBACKGROUND); ::GetClientRect (m_hWndMaster, &rcClient); ::GetUpdateRect(m_hWndMaster, &rcView, 0); if (m_bMasterInScroll || m_MasterBitmap.Flags.Allocated) { IntersectRect(&rcView, &m_rcDstMaster, &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; } L_BOOL CAPIWarpDlg::OnSlaveEraseBkgnd(HDC hDC) { HBRUSH hBrush; HRGN hClientRgn, hFillRgn; RECT rcView, rcClient; hBrush = (HBRUSH)GetClassLong(m_hWndSlave, GCL_HBRBACKGROUND); ::GetClientRect (m_hWndSlave, &rcClient); ::GetUpdateRect(m_hWndSlave, &rcView, 0); if (m_bSlaveInScroll || m_SlaveBitmap.Flags.Allocated) { IntersectRect(&rcView, &m_rcDstSlave, &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; } void CAPIWarpDlg::DisableMasterRadioButtons() { CButton *pCheck = (CButton *)GetDlgItem(IDC_MASTER_NORMALSIZE); pCheck->SetCheck(0); pCheck = (CButton *)GetDlgItem(IDC_MASTER_FIT_IMAGE); pCheck->SetCheck(0); } void CAPIWarpDlg::OnQueryNewPalette() { if (m_hMasterPalette) { DeleteObject(m_hMasterPalette); m_hMasterPalette = NULL; } if (m_MasterBitmap.Flags.Allocated) { CDC* pDC = GetDC(); m_hMasterPalette = L_CreatePaintPalette(pDC->m_hDC, &m_MasterBitmap); if(m_hMasterPalette) { HPALETTE OldPalette = ::SelectPalette(pDC->m_hDC, m_hMasterPalette, FALSE); if (pDC->RealizePalette()) InvalidateRect(NULL, FALSE); ::SelectPalette(pDC->m_hDC, OldPalette, TRUE); } ReleaseDC(pDC); } if (m_hSlavePalette) { ::DeleteObject(m_hSlavePalette); m_hSlavePalette = NULL; } if (m_SlaveBitmap.Flags.Allocated) { CDC* pDC = GetDC(); m_hSlavePalette = L_CreatePaintPalette(pDC->m_hDC, &m_SlaveBitmap); if (m_hSlavePalette) { HPALETTE OldPalette = ::SelectPalette(pDC->m_hDC, m_hSlavePalette, FALSE); if (RealizePalette(pDC->m_hDC)) InvalidateRect(NULL, FALSE); ::SelectPalette(pDC->m_hDC, OldPalette, TRUE); } ReleaseDC(pDC); } } void CAPIWarpDlg::OnPaletteChanged(CWnd* pFocusWnd) { if (GetSafeHwnd() == pFocusWnd->GetSafeHwnd()) return; if ((m_MasterBitmap.Flags.Allocated) && (m_hMasterPalette)) { CDC* pDC = GetDC(); HPALETTE OldPalette = ::SelectPalette(pDC->m_hDC, m_hMasterPalette, TRUE); pDC->RealizePalette(); InvalidateRect(NULL, FALSE); SelectPalette(pDC->m_hDC, OldPalette, FALSE); ReleaseDC(pDC); } if ((m_SlaveBitmap.Flags.Allocated) && (m_hSlavePalette)) { CDC* pDC = GetDC(); HPALETTE OldPalette = ::SelectPalette(pDC->m_hDC, m_hSlavePalette, TRUE); pDC->RealizePalette(); InvalidateRect(NULL, FALSE); ::SelectPalette(pDC->m_hDC, OldPalette, FALSE); ReleaseDC(pDC); } } void CAPIWarpDlg::OnZoomin() { if (m_nZoomFactor < 800) { // Increase the zoom factor m_nZoomFactor += 10; // Zoom the image SetZoomFactor(); } } void CAPIWarpDlg::OnZoomout() { if (m_nZoomFactor > 20) { // Decrease the zoom factor m_nZoomFactor -= 10; // Zoom the image SetZoomFactor(); } } L_VOID CAPIWarpDlg::SetZoomFactor() { DWORD dwStyle; int nHScroll, nVScroll; int nHeight, nWidth; RECT rcClient; int cxClient, cyClient; int x, y; ::GetClientRect (m_hWndMaster, &rcClient); cxClient = RECTWIDTH (&rcClient); cyClient = RECTHEIGHT (&rcClient); x = cxClient / 2; y = cyClient / 2; nWidth = MulDiv (BITMAPWIDTH(&m_MasterBitmap), m_nZoomFactor, 100); nHeight = MulDiv (BITMAPHEIGHT(&m_MasterBitmap), m_nZoomFactor, 100); dwStyle = GetWindowLong (m_hWndMaster, 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; } m_nMasterVscrollMax = max (0, (int) nHeight - (int) cyClient); m_nMasterHscrollMax = max (0, (int) nWidth - (int) cxClient); m_nMasterVscrollStep = max (1, cyClient / 10); m_nMasterHscrollStep = max (1, cxClient / 10); if(RECTWIDTH(&m_rcDstMaster)) m_nMasterHscrollPos = (int) ((long) (x - m_rcDstMaster.left) * nWidth / RECTWIDTH(&m_rcDstMaster)) - (cxClient / 2); if(RECTHEIGHT(&m_rcDstMaster)) m_nMasterVscrollPos = (int) ((long) (y - m_rcDstMaster.top) * nHeight / RECTHEIGHT(&m_rcDstMaster)) - (cyClient / 2); m_nMasterVscrollPos = max (0, min (m_nMasterVscrollPos, m_nMasterVscrollMax)); m_nMasterHscrollPos = max (0, min (m_nMasterHscrollPos, m_nMasterHscrollMax)); CheckDlgButton(IDC_MASTER_NORMALSIZE, 0); CheckDlgButton(IDC_MASTER_FIT_IMAGE, 0); // Update master scroll bars UpdateMasterScrollBar(FALSE); // Make the bitmap in center CenterBitmap(&m_rcDstMaster, m_hWndMaster); // Update polygon scale UpdatePolygonScale(); ::InvalidateRect(m_hWndMaster, NULL, TRUE); ::UpdateWindow(m_hWndMaster); return; } L_VOID CAPIWarpDlg::OnMasterHScroll(L_UINT uCode, L_INT nPos) { L_INT nScrollInc; RECT rcClient; m_bMasterInScroll = TRUE; ::GetClientRect(m_hWndMaster, &rcClient); switch (uCode) { case SB_LEFT: nScrollInc = -m_nMasterHscrollPos; break; case SB_RIGHT: nScrollInc = m_nMasterHscrollMax - m_nMasterHscrollPos; break; case SB_LINELEFT: nScrollInc = -m_nMasterHscrollStep; break; case SB_LINERIGHT: nScrollInc = m_nMasterHscrollStep; break; case SB_PAGELEFT: nScrollInc = -max (m_nMasterHscrollStep, (RECTWIDTH(&rcClient) - m_nMasterHscrollStep)); break; case SB_PAGERIGHT: nScrollInc = max (m_nMasterHscrollStep, (RECTWIDTH(&rcClient) - m_nMasterHscrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = nPos - m_nMasterHscrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-m_nMasterHscrollPos, min (nScrollInc, (m_nMasterHscrollMax - m_nMasterHscrollPos))); if(nScrollInc) { // Update the destination rectangle and scroll position m_nMasterHscrollPos += nScrollInc; OffsetRect(&m_rcDstMaster, -nScrollInc, 0); // Update the annotation offset L_AnnSetOffsetX(m_hContainer, (L_DOUBLE) m_rcDstMaster.left, ANNFLAG_NOINVALIDATE); ::ScrollWindow(m_hWndMaster, -nScrollInc, 0, NULL, NULL); ::SetScrollPos(m_hWndMaster, SB_HORZ, m_nMasterHscrollPos, TRUE); ::UpdateWindow(m_hWndMaster); } m_bMasterInScroll = FALSE; } L_VOID CAPIWarpDlg::OnMasterVScroll(L_UINT uCode, L_INT nPos) { L_INT nScrollInc; RECT rcClient; m_bMasterInScroll = TRUE; ::GetClientRect(m_hWndMaster, &rcClient); switch (uCode) { case SB_BOTTOM: nScrollInc = m_nMasterVscrollMax - m_nMasterVscrollPos; break; case SB_TOP: nScrollInc = -m_nMasterVscrollPos; break; case SB_LINEDOWN: nScrollInc = m_nMasterVscrollStep; break; case SB_LINEUP: nScrollInc = -m_nMasterVscrollStep; break; case SB_PAGEDOWN: nScrollInc = max (m_nMasterVscrollStep, (RECTHEIGHT(&rcClient) - m_nMasterVscrollStep)); break; case SB_PAGEUP: nScrollInc = -max (m_nMasterVscrollStep, (RECTHEIGHT(&rcClient) - m_nMasterVscrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = nPos - m_nMasterVscrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-m_nMasterVscrollPos, min (nScrollInc, (m_nMasterVscrollMax - m_nMasterVscrollPos))); if(nScrollInc) { // Update the destination rectangle and scroll position m_nMasterVscrollPos += nScrollInc; OffsetRect(&m_rcDstMaster, 0, -nScrollInc); // Update the annotation offset L_AnnSetOffsetY(m_hContainer, (L_DOUBLE) m_rcDstMaster.top, ANNFLAG_NOINVALIDATE); ::ScrollWindow(m_hWndMaster, 0, -nScrollInc, NULL, NULL); ::SetScrollPos(m_hWndMaster, SB_VERT, m_nMasterVscrollPos, TRUE); ::UpdateWindow(m_hWndMaster); } m_bMasterInScroll = FALSE; } L_VOID CAPIWarpDlg::OnSlaveHScroll(L_UINT uCode, L_INT nPos) { L_INT nScrollInc; RECT rcClient; // Get the client area ::GetClientRect(m_hWndSlave, &rcClient); switch (uCode) { case SB_LEFT: nScrollInc = -m_nSlaveHscrollPos; break; case SB_RIGHT: nScrollInc = m_nSlaveHscrollMax - m_nSlaveHscrollPos; break; case SB_LINELEFT: nScrollInc = -m_nSlaveHscrollStep; break; case SB_LINERIGHT: nScrollInc = m_nSlaveHscrollStep; break; case SB_PAGELEFT: nScrollInc = -max (m_nSlaveHscrollStep, (RECTWIDTH(&rcClient) - m_nSlaveHscrollStep)); break; case SB_PAGERIGHT: nScrollInc = max (m_nSlaveHscrollStep, (RECTWIDTH(&rcClient) - m_nSlaveHscrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = nPos - m_nSlaveHscrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-m_nSlaveHscrollPos, min (nScrollInc, (m_nSlaveHscrollMax - m_nSlaveHscrollPos))); if(nScrollInc) { // Update the destination rectangle and scroll position m_nSlaveHscrollPos += nScrollInc; OffsetRect(&m_rcDstSlave, -nScrollInc, 0); ::ScrollWindow(m_hWndSlave, -nScrollInc, 0, NULL, NULL); ::SetScrollPos(m_hWndSlave, SB_HORZ, m_nSlaveHscrollPos, TRUE); ::UpdateWindow(m_hWndSlave); } } L_VOID CAPIWarpDlg::OnSlaveVScroll(L_UINT uCode, L_INT nPos) { L_INT nScrollInc; RECT rcClient; // Get the slave client rect ::GetClientRect(m_hWndSlave, &rcClient); // Find the new scroll pos switch (uCode) { case SB_BOTTOM: nScrollInc = m_nSlaveVscrollMax - m_nSlaveVscrollPos; break; case SB_TOP: nScrollInc = -m_nSlaveVscrollPos; break; case SB_LINEDOWN: nScrollInc = m_nSlaveVscrollStep; break; case SB_LINEUP: nScrollInc = -m_nSlaveVscrollStep; break; case SB_PAGEDOWN: nScrollInc = max (m_nSlaveVscrollStep, (RECTHEIGHT(&rcClient) - m_nSlaveVscrollStep)); break; case SB_PAGEUP: nScrollInc = -max (m_nSlaveVscrollStep, (RECTHEIGHT(&rcClient) - m_nSlaveVscrollStep)); break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nScrollInc = nPos - m_nSlaveVscrollPos; break; default: nScrollInc = 0; break; } nScrollInc = max (-m_nSlaveVscrollPos, min (nScrollInc, (m_nSlaveVscrollMax - m_nSlaveVscrollPos))); if(nScrollInc) { // Update the destination rectangle and scroll position m_nSlaveVscrollPos += nScrollInc; OffsetRect(&m_rcDstSlave, 0, -nScrollInc); ::ScrollWindow(m_hWndSlave, 0, -nScrollInc, NULL, NULL); ::SetScrollPos(m_hWndSlave, SB_VERT, m_nSlaveVscrollPos, TRUE); ::UpdateWindow(m_hWndSlave); } }