home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************/
- /* */
- /* TurboCAD for Windows */
- /* Copyright (c) 1993 - 2001 */
- /* International Microcomputer Software, Inc. */
- /* (IMSI) */
- /* All rights reserved. */
- /* */
- /******************************************************************/
-
- // AutoJPEG.cpp : implementation file
- //
-
- #include "stdafx.h"
- #include "JPEG.h"
- #include "AutoJPEG.h" // This class
-
- // How to create a JPEG?
- #ifdef USE_LEADTOOOLS
- // Source code license required
- #else
- // Exported function from JPEGLIB.DLL
- __declspec(dllimport) extern "C" int DIBToJPEG(HGLOBAL hDib, LPCSTR outfilename);
- #endif
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- // Standard variants
- COleVariant t(-1L, VT_BOOL);
- COleVariant f(0L, VT_BOOL);
- COleVariant missing((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
-
- // IID's From Imsigx.i_c.
- const IID IID_Graphics =
- {0x6A48110A,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
- const IID IID_Filter =
- {0x6A48111B,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
-
- /////////////////////////////////////////////////////////////////////////////
- // CAutoJPEG
-
- // We get all these functions from the Visual C++ ClassWizard...
-
- IMPLEMENT_DYNCREATE(CAutoJPEG, CCmdTarget)
-
- CAutoJPEG::CAutoJPEG()
- {
- EnableAutomation();
-
- // To keep the application running as long as an OLE automation
- // object is active, the constructor calls AfxOleLockApp.
-
- AfxOleLockApp();
- }
-
- CAutoJPEG::~CAutoJPEG()
- {
- // To terminate the application when all objects created with
- // with OLE automation, the destructor calls AfxOleUnlockApp.
-
- AfxOleUnlockApp();
- }
-
-
- void CAutoJPEG::OnFinalRelease()
- {
- // When the last reference for an automation object is released
- // OnFinalRelease is called. The base class will automatically
- // deletes the object. Add additional cleanup required for your
- // object before calling the base class.
-
- CCmdTarget::OnFinalRelease();
- }
-
-
- BEGIN_MESSAGE_MAP(CAutoJPEG, CCmdTarget)
- //{{AFX_MSG_MAP(CAutoJPEG)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- BEGIN_DISPATCH_MAP(CAutoJPEG, CCmdTarget)
- //{{AFX_DISPATCH_MAP(CAutoJPEG)
- DISP_PROPERTY_EX(CAutoJPEG, "ClassID", GetClassID, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CAutoJPEG, "Description", GetDescription, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CAutoJPEG, "Info", GetInfo, SetNotSupported, VT_BSTR)
- DISP_PROPERTY_EX(CAutoJPEG, "LastError", GetLastError, SetNotSupported, VT_BSTR)
- DISP_FUNCTION(CAutoJPEG, "CheckFlat", CheckFlat, VT_I4, VTS_DISPATCH VTS_BSTR VTS_I4 VTS_PVARIANT)
- DISP_FUNCTION(CAutoJPEG, "PreviewFlat", PreviewFlat, VT_I4, VTS_DISPATCH VTS_BSTR VTS_I4 VTS_I4 VTS_PBSTR VTS_PVARIANT)
- // decoment second string to get this filter in OpenFile filters list
- // DISP_FUNCTION(CAutoJPEG, "ReadFlat", ReadFlat, VT_I4, VTS_BSTR VTS_I4 VTS_DISPATCH VTS_PVARIANT)
- DISP_FUNCTION(CAutoJPEG, "WriteFlat", WriteFlat, VT_I4, VTS_BSTR VTS_I4 VTS_DISPATCH VTS_PVARIANT)
- DISP_FUNCTION(CAutoJPEG, "ReadSetup", ReadSetup, VT_BOOL, VTS_DISPATCH)
- DISP_FUNCTION(CAutoJPEG, "WriteSetup", WriteSetup, VT_BOOL, VTS_DISPATCH)
- DISP_FUNCTION(CAutoJPEG, "Initialize", Initialize, VT_BOOL, VTS_DISPATCH)
- //}}AFX_DISPATCH_MAP
- END_DISPATCH_MAP()
-
- // Note: we add support for IID_ITurboCADFilter to support typesafe binding
- // from VBA. This IID must match the GUID that is attached to the
- // dispinterface in the .ODL file. Do not change this GUID if make your own custom filter!
-
- // {6A481302-E531-11CF-A115-00A024158DAF}
- static const IID IID_ITurboCADFilter =
- {0x6A481302,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
-
- BEGIN_INTERFACE_MAP(CAutoJPEG, CCmdTarget)
- INTERFACE_PART(CAutoJPEG, IID_ITurboCADFilter, Dispatch)
- END_INTERFACE_MAP()
-
- // Note: if you make a custom filter by copying this file, make sure to replace the following
- // GUID with a new GUID that matches the uuid statement in the coclass declaration in the
- // .ODL file. This is the GUID that OLE will use to register and create the automation object.
-
- // {28696026-B7E6-11D0-9B3B-444553540000}
- IMPLEMENT_OLECREATE(CAutoJPEG, "JPEG.AutoJPEG", 0x28696026, 0xb7e6, 0x11d0, 0x9b, 0x3b, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0)
-
- /////////////////////////////////////////////////////////////////////////////
- // CAutoJPEG message handlers
-
- // GetClassID: return the filter's class id, as a string.
-
- BSTR CAutoJPEG::GetClassID()
- {
- // Convert our GUID (see IMPLEMENT_OLECREATE macro) to a string
- LPOLESTR olestr;
- HRESULT hRes = ::StringFromCLSID(guid, &olestr);
- if (FAILED(hRes))
- return NULL;
-
- BSTR bstr = ::SysAllocString(olestr);
- CoTaskMemFree(olestr);
- return bstr;
- }
-
- // GetDescription: return the filter's description.
-
- BSTR CAutoJPEG::GetDescription()
- {
- // Get the description from the resource
- CString strResult;
- strResult.LoadString(IDS_AUTOJPEG_DESC);
-
- return strResult.AllocSysString();
- }
-
- // GetInfo: return the filter's info string
- // Our info string is "JPEG.AutoJPEG,JPEG (JFIF) File,0,10,JPG,JPG", stored in the DLL's
- // resource.
-
- // The info string contains the following fields, delimited by commas:
- // Field Name Value
- // 1. Filter ID "JPEG.AutoJPEG"
- // Used as the internal name (must be unique).
- // Should be the same as the ProgID registered for the server.
- // TurboCAD reserves names beginning with an asterisk.
- // 2. File type string for common dialog "JPEG (JFIF) File";
- // This string appears in Windows dialog file type combo box.
- // 3. Document type handled by filter 0
- // This should always be zero for automation filters.
- // 4. Priority 10
- // Arbitrary integer value used to determine search order for multiple filters which
- // support the same document type and file extension.
- // 5. Exported function name prefix "JPG"
- // Not used by automation filters, but a non-blank string must be supplied.
- // 6-n. File extensions "JPG"
- // Used in common dialog and for matching.
-
- BSTR CAutoJPEG::GetInfo()
- {
- // Get the description from the resource
- CString strResult;
- strResult.LoadString(IDS_AUTOJPEG_INFO);
-
- return strResult.AllocSysString();
- }
-
-
- // GetLastError: return descriptive information about the last error that occurred during an
- // open or save operation. A smarter filter would save state somewhere and return better
- // diagnostics.
-
- BSTR CAutoJPEG::GetLastError()
- {
- CString strResult;
- strResult.LoadString(IDS_AUTOJPEG_ERROR_UNKNOWN);
-
- return strResult.AllocSysString();
- }
-
- // CheckFlat: file readers get called with this method to see if they can read the file.
- // If we were a file reader, we would look for a JPEG header.
-
- long CAutoJPEG::CheckFlat(LPDISPATCH ThisFilter, LPCTSTR FileName, long ContextFlags, VARIANT FAR* QueryString)
- {
- // We are not implementing a reader
- AfxThrowOleException(E_NOTIMPL);
- return 0;
- }
-
- // PreviewFlat: file readers get called with this method to get a description string and a
- // (bitmap or metafile) thumbnail from the file. If we were a file reader, we would create a
- // bitmap or StdPicture object from the JPEG file.
-
- long CAutoJPEG::PreviewFlat(LPDISPATCH ThisFilter, LPCTSTR FileName, long ThumbWidth, long ThumbHeight, BSTR FAR* Description, VARIANT FAR* Thumbnail)
- {
- // We are not implementing a reader
- AfxThrowOleException(E_NOTIMPL);
- return 0;
- }
-
- // ReadFlat: file readers get called with this method to read graphics from the file and
- // add to the Graphics collection. The Drawing object that we're reading into can be
- // obtained by calling Graphics->get_Drawing.
-
- long CAutoJPEG::ReadFlat(LPCTSTR FileName, long ContextFlags, LPDISPATCH Graphics, VARIANT FAR* QueryString)
- {
- // We are not implementing a reader
- AfxThrowOleException(E_NOTIMPL);
- return 0;
- }
-
- // WriteFlat: file writers get called with this method to write graphics to the file.
- // The Drawing object that we're writing from from is obtained by calling Graphics->get_Drawing.
-
- long CAutoJPEG::WriteFlat(LPCTSTR FileName, long ContextFlags, LPDISPATCH Grfs, VARIANT FAR* QueryString)
- {
- long nError = -101;
-
- try
- {
- Graphics* pGraphics = NULL;
- if (FAILED(Grfs->QueryInterface(IID_Graphics, (void**)&pGraphics)))
- return -101;
-
- #ifdef USE_LEADTOOLS
- // Source code license required!
-
- // If we were licensed, we could accomplish the task as follows:
- // 1. Use LEADTOOLS to get a (bitmap) DC to draw onto.
- // 2. Set up a View on our drawing with this DC.
- // 3. Refresh the View (painting onto its DC).
- // 4. Let LEADTOOLS or another utility to save the bitmap on the DC to a JPEG file.
- // 5. Destroy the DC.
-
- #else
- // Since we're using our custom JPEG library (which expects a DIB in memory), we will:
- // 1. Set up a View on our drawing (no DC necessary).
- // 2. Open a bitmap DC on the View.
- // 3. Refresh the View (painting onto its DC).
- // 4. Close the bitamp DC and retrieve the DIB.
- // 5. Pass the DIB to our special function DIBToJPEG.
- // 6. Dispose of the memory in the DIB.
-
- // Copyright notice: DIBToJPEG is an exported function, part of a DLL created using the
- // Independent JPEG Group's JPEG encoding/decoding library, modified in part by IMSI.
- // Please read the file "README" that is in this directory for more information on
- // JPEG, the IJG and the JPEG library.
-
- // long nError = -101;
-
- HGLOBAL hDib = NULL;
- IDrawing* pIDrawing = NULL;
- if (SUCCEEDED(pGraphics->get_Drawing(&pIDrawing)))
- {
- Views* pViews = NULL;
- if (SUCCEEDED(pIDrawing->get_Views(&pViews)))
- {
- View* pView = NULL;
- if (SUCCEEDED(pViews->Add(&missing, &missing, &pView)))
- {
- // To set the image width and height, we use settings stored in
- // TurboCAD's INI file. These settings are transfered to our
- // WriteSetup dialog for use by us. See comments on the WriteSetup
- // function below, and the code in WSetup.cpp for more information.
- IApplication* pIApp;
- if (SUCCEEDED(pGraphics->get_Application(&pIApp)))
- {
- CString strProfileName;
- if (GetProfileName(pIApp, strProfileName))
- m_dlg.FromProfile(strProfileName);
- pIApp->Release();
- }
-
- // Set up size for bitmap DC
- HRESULT hRes;
- hRes = pView->put_Update(FALSE);
- hRes = pView->put_MappingMode(MM_TEXT);
- hRes = pView->put_ScreenLeft(0.0);
- hRes = pView->put_ScreenTop(0.0);
- hRes = pView->put_ScreenWidth((double)m_dlg.m_nWidth);
- hRes = pView->put_ScreenHeight((double)m_dlg.m_nHeight);
- hRes = pView->ZoomToExtents();
- hRes = pView->put_Update(TRUE);
-
- // Draw our extents on the View as a bitmap
- long lBitmapDC = 0;
- hRes = pView->OpenBitmapDC(&lBitmapDC);
- if (SUCCEEDED(hRes))
- {
- hRes = pView->Refresh();
- hRes = pView->CloseBitmapDC((long*)&hDib);
- }
-
- // Done with view
- pView->Delete();
- pView->Release();
- }
- pViews->Release();
- }
- pIDrawing->Release();
- }
-
- if (hDib != NULL)
- {
- // Use function in JPEGLIB.DLL to save as a JPEG(JFIF) file
- // Should work with 8, 16, and 24-bit DIBs
- nError = DIBToJPEG(hDib, FileName);
- ::GlobalFree(hDib);
- }
- #endif
-
- pGraphics->Release();
- }
- catch(...)
- {
- TRACE("Exception in CAutoJPEG::WriteFlat");
- }
- if (nError == -555)
- {
- AfxMessageBox("This sample doesn't work for display setting True Color (32 Bit)!");
- nError = 0;
- }
- return nError;
- }
-
- // ReadSetup: called to allow user interface for file read settings.
-
- BOOL CAutoJPEG::ReadSetup(LPDISPATCH ThisFilter)
- {
- // We are not implementing a reader.
- AfxThrowOleException(E_NOTIMPL);
-
- return TRUE;
- }
-
- // WriteSetup: called to allow user interface for file write settings.
- // Our example allows users to specify the width and height of the JPEG image.
- // We could (with a little more work) control the bit depth, compression, etc.
-
- BOOL CAutoJPEG::WriteSetup(LPDISPATCH ThisFilter)
- {
- // We store these settings in TurboCAD's INI file.
- // First, get the file name.
- CString strProfileName;
- if (ThisFilter != NULL)
- {
- Filter* pFilter;
- HRESULT hRes = ThisFilter->QueryInterface(IID_Filter, (void**)&pFilter);
- if (SUCCEEDED(hRes))
- {
- IApplication* pIApp;
- hRes = pFilter->get_Application(&pIApp);
- if (SUCCEEDED(hRes))
- {
- GetProfileName(pIApp, strProfileName);
- pIApp->Release();
- }
- pFilter->Release();
- }
- }
-
- // Initialize the setup dialog from the INI file, and run the dialog.
- if (!strProfileName.IsEmpty())
- m_dlg.FromProfile(strProfileName);
- if (m_dlg.DoModal() == IDOK)
- {
- // Update the INI file if the user clicked OK
- if (!strProfileName.IsEmpty())
- m_dlg.ToProfile(strProfileName);
- }
- return TRUE;
- }
-
- // Function called when Filter object has been added to application at startup.
- // We could install an event listener here, allocate memory, or whatever.
-
- BOOL CAutoJPEG::Initialize(LPDISPATCH ThisFilter)
- {
- // We just return TRUE for success. Returning FALSE would remove our Filter.
- return TRUE;
- }
-
- // Helper function for filter settings (accessed in WriteSetup).
- // We will store our settings in TurboCAD's INI file.
- // Another option is to store the settings in the Windows registry.
-
- BOOL CAutoJPEG::GetProfileName(IApplication* pIApp, CString& strProfileName)
- {
- BSTR bstrProfile;
- HRESULT hRes = pIApp->get_ProfileName(0, &bstrProfile);
- if (SUCCEEDED(hRes))
- {
- strProfileName = bstrProfile;
- ::SysFreeString(bstrProfile);
- return TRUE;
- }
- return FALSE;
- }
-
- // DUAL_SUPPORT_START
- // The rest of this file is boilerplate dual interface stuff. We use macros from MfcDual.h
- // and just wrap all of our implementation functions in TRY/CATCH blocks.
-
- // delegate standard IDispatch methods to MFC IDispatch implementation
- DELEGATE_DUAL_INTERFACE(CAutoJPEG, DualJPEG)
-
- // Our method and property functions can generally just
- // delegate back to the methods we generated using
- // ClassWizard. However, if we set up properties to
- // access variables directly, we will need to write the
- // code to get/put the value into the variable.
- STDMETHODIMP CAutoJPEG::XDualJPEG::get_ClassID(BSTR FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->GetClassID();
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::get_Description(BSTR FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->GetDescription();
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::get_Info(BSTR FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->GetInfo();
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::get_LastError(BSTR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->GetLastError();
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::CheckFlat(IDispatch* ThisFilter, BSTR FileName, long ContextFlags, VARIANT FAR* QueryString, long FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- CString strFileName(FileName);
- *retval = pThis->CheckFlat(ThisFilter, strFileName, ContextFlags, QueryString);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::PreviewFlat(IDispatch* ThisFilter, BSTR FileName, long ThumbWidth, long ThumbHeight, BSTR FAR* Description, VARIANT FAR* Thumbnail, long FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- CString strFileName(FileName);
- *retval = pThis->PreviewFlat(ThisFilter, strFileName, ThumbWidth, ThumbHeight, Description, Thumbnail);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::ReadFlat(BSTR FileName, long ContextFlags, IDispatch * Graphics, VARIANT FAR* QueryString, long FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- CString strFileName(FileName);
- *retval = pThis->ReadFlat(strFileName, ContextFlags, Graphics, QueryString);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::WriteFlat(BSTR FileName, long ContextFlags, IDispatch * Graphics, VARIANT FAR* QueryString, long FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- CString strFileName(FileName);
- *retval = pThis->WriteFlat(strFileName, ContextFlags, Graphics, QueryString);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::ReadSetup(IDispatch* ThisFilter, VARIANT_BOOL FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->ReadSetup(ThisFilter);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::WriteSetup(IDispatch* ThisFilter, VARIANT_BOOL FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->WriteSetup(ThisFilter);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- STDMETHODIMP CAutoJPEG::XDualJPEG::Initialize(IDispatch* ThisFilter, VARIANT_BOOL FAR* retval)
- {
- if (retval == NULL)
- return E_POINTER;
-
- METHOD_PROLOGUE(CAutoJPEG, DualJPEG)
-
- TRY_DUAL(IID_ITurboCADFilter)
- {
- *retval = pThis->Initialize(ThisFilter);
- return S_OK;
- }
- CATCH_ALL_DUAL
- }
-
- // Implement ISupportErrorInfo to indicate we support the
- // OLE Automation error handler.
- IMPLEMENT_DUAL_ERRORINFO(CAutoJPEG, IID_ITurboCADFilter)
-
- // DUAL_SUPPORT_END
-
-
-
-