// ========================================================================== // Class Specification : COXImageViewer // ========================================================================== // Header file : OXImageViewer.h // Version: 9.3 // This software along with its related components, documentation and files ("The Libraries") // is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is // governed by a software license agreement ("Agreement"). Copies of the Agreement are // available at The Code Project (www.codeproject.com), as part of the package you downloaded // to obtain this file, or directly from our office. For a copy of the license governing // this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900. // ////////////////////////////////////////////////////////////////////////// // /* DESCRIPTION The COXImageViewer class is COXScrollWnd based class which is desined to display DIB and, optionally, JPEG images. As long its base class is COXScrollWnd it automatically support the following features: Scrolling of the image if it is larger then the client area size Zooming of the image: 10% to 100% Image can be aligned vertically and horizontally. Supports smooth scrolling which means that the process of scrolling of the image from one position to another is divided in a number of smaller scrolling processes Supports 'Always fit to window' option that if set will scale the image of the control to its size whenever it is resized Context menu can be displayed that allows a user easily set image display setting (will be described in details below) Track zooming option is supported which means that when a user left clicks and drag the mouse cursor the tracker will be displayed so a user can choose the rectangle to which the image must be zoomed Scrolling using mouse wheel is supported Optional support for ruler bars (using COXRulerBarOrganizer class) Refer to COXScrollWnd description and class reference for details on the functionality provided by this class. Here we will concentrate on the functionality that is unique for the COXImageViewer class. Internally COXImageViewer uses COXDIB object (COXDIB class is part of the Ultimate Toolbox library) in order to load and display an image. This internal object can be retrieved and all set of the COXDIB class functions can be applied to it. Usage In order to use COXImageViewer object in your application you have to create it using standard CWnd::Create function. After control was successfully created you have to load the image that is to be displayed using: BOOL LoadImage(const COXDIB& dib); virtual BOOL LoadFile(LPCTSTR lpszPathName); virtual BOOL LoadFile(CFile* pFile); virtual BOOL LoadResource(LPCTSTR lpszResource); BOOL LoadResource(UINT nIDResource); #ifdef OXDIB_SUPPORTJPEG virtual BOOL LoadJPEGFile(LPCTSTR lpszPathName); #endif As you can see an image can be loaded from existing COXDIB object, file, or resource. Also we provide an optional support for displaying JPEG images (call LoadJPEGFile() function in order to load JPEG file) but only if you add the following define into your "stdafx.h" file or project preprocessor definitions list: #define OXDIB_SUPPORTJPEG After image is loaded it will be displayed at zoom level of 100% in top left of the window unless you specify otherwise using COXScrollWnd functions that deal with contents alignment and zoom level. Then you can change the loaded image by retrieving a pointer to internal COXDIB object and calling COXDIB functions. COXDIB* GetImage(); E.g. you can change the size of the image, rotate and flip it. Then you can save any changes made to the object into DIB or JPEG, if supported, file. E.g. in order to save the image associated with COXImageViewer object you might call: GetImage()->WriteJPEG(_T("MyImage.jpg")); Refer to COXDIB class reference for details on all functions available. The last thing we would like to mention is that in the case when >=256 color image must be displayed in 256-color video mode you have provide some additional functionality in applications that use the COXImageViewer class. COXDIB provides us with information about the palette that should be used in order to get the best results while displaying the image. The problem is that only top-level windows will get messages that notify a window that it should release its own palette. These messages are: WM_PALETTECHANGED WM_QUERYNEWPALETTE You as a programmer have to make sure that these messages will be forwarded to all currently active COXImageViewer objects from main window of your application. E.g. in the case of MDI or SDI application you can add the following handlers to your CMainFrame window: void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd) { CMDIFrameWnd::OnPaletteChanged(pFocusWnd); // TODO: Add your message handler code here SendMessageToDescendants(WM_PALETTECHANGED, (pFocusWnd!=NULL ? (WPARAM)pFocusWnd->GetSafeHwnd() : NULL)); } BOOL CMainFrame::OnQueryNewPalette() { // TODO: Add your message handler code here and/or call default SendMessageToDescendants(WM_QUERYNEWPALETTE); return CMDIFrameWnd::OnQueryNewPalette(); } This messages will be eventually handled by COXImageViewer objects and images will be displayed in the most appropriate way. Of course this approach will work only for COXImageViewer controls that are CMainFrame descendants. If you need to explicitly release the palette associated with the image you can call the following function: UINT DoRealizePalette(); The sample that demonstrates COXImageViewer class is called ImageViewer and can be found in the .\Samples\graphics\ImageViewer subdirectory of your Ultimate Toolbox directory. Dependency: #include "OXImageViewer.h" Source code files: "OXImageViewer.cpp" "OXScrollWnd.cpp" - COXScrollWnd implementation #ifdef OXSCRLWND_USE_RULER "OXRulerOrganizer.cpp" - COXRulerOrganizer implementation "OXHookWnd.cpp" - implementation of the COXHookWnd class from which the COXRulerOrganizer class is derived #endif "OXDIB.cpp" - COXDIB implementation #ifdef OXDIB_SUPPORTJPEG "OXBmpFle.cpp" "OXGphFle.cpp" "OXJPGCod.cpp" "OXJPGCom.cpp" - JPEG support "OXJPGDom.cpp" "OXJPGExp.cpp" "OXJPGFle.cpp" #endif */ #if !defined(_OXIMAGEVIEWER_H__) #define _OXIMAGEVIEWER_H__ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include "OXDllExt.h" // OXImageViewer.h : header file // #include "OXDIB.h" #include "OXScrollWnd.h" #include "OXMainRes.h" // ////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // COXImageViewer window class OX_CLASS_DECL COXImageViewer : public COXScrollWnd { DECLARE_DYNAMIC(COXImageViewer) // Construction public: // --- In : // --- Out : // --- Returns: // --- Effect: Contructs the object COXImageViewer(); // Attributes public: protected: // number of colors used in current video mode static int m_nDisplayColors; // DIB image COXDIB m_dib; // special DIB object that we use to render the image on the screen // in the case when the current system palette is no more than 8 bits // and image consist of no less than 256 colors COXDIB m_dibDither; // background color COLORREF m_clrBackground; // Operations public: // --- In : dib - reference to COXDIB object that must be displayed. // The copy of the object will be made and saved // internally // --- Out : // --- Returns: TRUE if image was loaded successfully // --- Effect: Copies specified COXDIB object and display it inline BOOL LoadImage(const COXDIB& dib) { m_dib=dib; return InitializeImage(); } // --- In : lpszPathName - filename of a DIB file to be displayed // in the image viewer // pFile - pointer to open CFile object // --- Out : // --- Returns: TRUE if file was loaded successfully // --- Effect: copies COXDIB object to be displayed in the image viewer from // the specified source (file on disk or open CFile object) virtual BOOL LoadFile(LPCTSTR lpszPathName); virtual BOOL LoadFile(CFile* pFile); // --- In : lpszResource - resource string that identifies a DIB // resources to be displayed in the image viewer // nIDResource - resource ID that identifies a DIB // resources to be displayed in the image viewer // --- Out : // --- Returns: TRUE if resource was loaded successfully // --- Effect: copies COXDIB object to be displayed in the image viewer from // the specified resource virtual BOOL LoadResource(LPCTSTR lpszResource); inline BOOL LoadResource(UINT nIDResource) { return LoadResource(MAKEINTRESOURCE(nIDResource)); } #ifdef OXDIB_SUPPORTJPEG // --- In : lpszPathName - filename of a JPEG file to be displayed // in the image viewer // pFile - pointer to open CFile object // --- Out : // --- Returns: TRUE if file was loaded successfully // --- Effect: reads JPEG file and converts it internally into COXDIB object // to be displayed in the image viewer. In order to use this // function you must add the following line into your "stdafx.h" file // or project settings: // // #define OXDIB_SUPPORTJPEG // // All convertion logic is implemented in COXDIB class virtual BOOL LoadJPEGFile(LPCTSTR lpszPathName); virtual BOOL LoadJPEGFile(CFile* pFile); #endif // --- In : bRedraw - if TRUE then image will be redrawn // --- Out : // --- Returns: TRUE if contents was successfully emptied // --- Effect: Resets the contents of the image viewer virtual BOOL Empty(BOOL bRedraw=TRUE); // --- In : // --- Out : // --- Returns: TRUE if any image is displayed // --- Effect: Retrieves the flag that specifies whether any image is displayed virtual BOOL IsEmpty() const { return m_dib.IsEmpty(); } // --- In : bRedraw - if TRUE then image will be redrawn // --- Out : // --- Returns: TRUE if image was successfully updated // --- Effect: call this function any time the image parameters // has been changed. E.g. using GetImage() function you can // get a pointer to internal image object and you can call // COXDIB functions (rotation, resizing, etc.) that might change // the image charecterstics. After you did it you must call this // function in order to display the image in the updated state. BOOL UpdateImage(BOOL bRedraw=TRUE); // --- In : // --- Out : // --- Returns: pointer to the COXDIB object used internally to display the image. // --- Effect: retrieves pointer to the COXDIB object used internally to // display the image. If you call any COXDIB function that might // change the appearance of the image (rotation, resizing, etc.), // make sure that you call UpdateImage() function in order to // display the image in the updated state. // If you want to save any changes made to the image in the // image viewer (e.g. you've rotated the image) you have to call this // function in order to retrieve the pointer to COXDIB object and // then call COXDIB::Write() function. If you want to save the image // as JPEG file call the COXDIB::WriteJPEG() function. inline COXDIB* GetImage() { return &m_dib; } // --- In : // --- Out : // --- Returns: pointer to the COXDIB object used internally to display // the dithered version of the original true-color image // which is used when 256-color video mode is active. // --- Effect: retrieves pointer to the COXDIB object used internally to // display the dithered version of the original true-color image // which is used when 256-color video mode is active. // Any changes you might made to this object will be discarded // next time when UpdateImage() function is called. It means that // you must treat this object as "read-only" inline COXDIB* GetDitheredImage() { return &m_dibDither; } // --- In : bRedraw - if TRUE then image will be redrawn // bForeground - if TRUE then palette will be forced to be // a foreground palette, otherwise, to be // a background palette // --- Out : // --- Returns: indicates how many entries in the logical palette were mapped // to different entries in the system palette. This represents // the number of entries that this function remapped to accommodate // changes in the system palette since the logical palette was // last realized. // --- Effect: call this function any time current palette has been changed. // Relevant only when 256-color video mode is set UINT DoRealizePalette(BOOL bRedraw=TRUE, BOOL bForeground=TRUE); // --- In : // --- Out : // --- Returns: Background color // --- Effect: Retrieves background color value inline COLORREF GetBackgroundColor() const { return m_clrBackground; } // --- In : clrBackground - background color // bRedraw - if TRUE then the contents will be redrawn // --- Out : // --- Returns: // --- Effect: Sets the background color value void SetBackgroundColor(COLORREF clrBackground, BOOL bRedraw=TRUE); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(COXImageViewer) //}}AFX_VIRTUAL // Implementation public: // --- In : // --- Out : // --- Returns: // --- Effect: Destructs the object virtual ~COXImageViewer(); protected: // retrieves pointer to the image palette. Automatically handles the case when // ditthered image palette must be retrieved CPalette* GetDIBPalette(); // retrieves size of the image in pixels CSize GetDIBSize(); // initialize scrolling settings for the image. Might be overriden // in order to specify different from default scrolling settings. virtual BOOL InitializeImage(const CSize& sizePage=CSize(100,100), const CSize& sizeLine=CSize(10,10)); // returns TRUE if the dithered image must be displayed instead of the // original one BOOL CheckUseDithered(); // returns TRUE if image palette must be selected/realized before // drawing the image BOOL CheckUsePalette(); // helper function that draws the specified part of the image // in the specified rectangle on the window virtual BOOL DrawDIB(CDC* pDC, const CRect& rectDest, const CRect& rectSrc); // virtual COXScrollWnd function, overriden in order to populate // context menu with items for rotation and flipping operations. virtual BOOL OnPopulateContextMenu(CMenu* pMenu, CPoint& point); // Generated message map functions protected: //{{AFX_MSG(COXImageViewer) afx_msg void OnPaint(); afx_msg void OnSetFocus(CWnd* pOldWnd); afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection); afx_msg void OnPaletteChanged(CWnd* pFocusWnd); afx_msg BOOL OnQueryNewPalette(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG afx_msg void OnRotate(UINT nID); afx_msg void OnFlip(UINT nID); afx_msg void OnAlign(UINT nID); DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(_OXIMAGEVIEWER_H__)