1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How to enable scrollbars in DIBLOOK result window

Discussion in 'MFC' started by szmitek, Dec 20, 2011.

  1. szmitek

    szmitek New Member

    Joined:
    Dec 19, 2011
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Chotomów, Poland
    Home Page:
    I am editing MFC program which is changed version (not by me) of Microsoft DIBLOOK sample. This program alow to open DIB image, edit it and show result in another window. Open images are showed in windows with scrollbars and edited (result) images are showed in windows without scrollbars. I want windows with edited images (result) to have scrollbars. How to do that windows with edited images have scrollbars? Could you help me?

    I have pasted code of the most important files below. I added other project files in attachements into DIBLOOK2.zip. I also added sample DIB image in LENA1X2.zip attachement. Microsoft DIBLOOK sample is created for Visual Studio 6 but this version is upgrade (not by me) for Visual Studio 2010.

    diview.cpp file (void CDibView::OperationOnCopy(pfnCDibDoc op) is method which show edited image, void CDibView::OnGray() cause image operation):

    Code:
    #include "stdafx.h"
    #include "diblook.h"
    
    #include "dibdoc.h"
    #include "dibview.h"
    #include "OutDoc.h"
    
    #include "dibapi.h"
    #include "mainfrm.h"
    #include "parametr.h"
    
    #ifdef _DEBUG
    #undef THIS_FILE
    static char BASED_CODE THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibView
    
    IMPLEMENT_DYNCREATE(CDibView, CScrollView)
    
    BEGIN_MESSAGE_MAP(CDibView, CScrollView)
        //{{AFX_MSG_MAP(CDibView)
        ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
        ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
        ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
        ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
        ON_MESSAGE(WM_DOREALIZE, OnDoRealize)
        ON_COMMAND(ID_GRAY, OnGray)
        ON_COMMAND(ID_BLOCK, OnBlock)
        //}}AFX_MSG_MAP
    
        // Standard printing commands
        ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibView construction/destruction
    
    CDibView::CDibView()
    {
        
    }
    
    CDibView::~CDibView()
    {
    }
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibView drawing
    
    void CDibView::OnDraw(CDC* pDC)
    {
        CDibDoc* pDoc = GetDocument();
        this->EnableScrollBar(SB_BOTH);
        HDIB hDIB = pDoc->GetHDIB();
        if (hDIB != NULL)
        {
            LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
            int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x
            int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y
            ::GlobalUnlock((HGLOBAL) hDIB);
            CRect rcDIB;
            rcDIB.top = rcDIB.left = 0;
            rcDIB.right = cxDIB;
            rcDIB.bottom = cyDIB;
            CRect rcDest;
            if (pDC->IsPrinting())   // printer DC
            {
                // get size of printer page (in pixels)
                int cxPage = pDC->GetDeviceCaps(HORZRES);
                int cyPage = pDC->GetDeviceCaps(VERTRES);
                // get printer pixels per inch
                int cxInch = pDC->GetDeviceCaps(LOGPIXELSX);
                int cyInch = pDC->GetDeviceCaps(LOGPIXELSY);
    
                //
                // Best Fit case -- create a rectangle which preserves
                // the DIB's aspect ratio, and fills the page horizontally.
                //
                // The formula in the "->bottom" field below calculates the Y
                // position of the printed bitmap, based on the size of the
                // bitmap, the width of the page, and the relative size of
                // a printed pixel (cyInch / cxInch).
                //
                rcDest.top = rcDest.left = 0;
                rcDest.bottom = (int)(((double)cyDIB * cxPage * cyInch)
                        / ((double)cxDIB * cxInch));
                rcDest.right = cxPage;
            }
            else   // not printer DC
            {
                rcDest = rcDIB;
            }
            ::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(),
                &rcDIB, pDoc->GetDocPalette());
        }
    }
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibView printing
    
    BOOL CDibView::OnPreparePrinting(CPrintInfo* pInfo)
    {
        // default preparation
        return DoPreparePrinting(pInfo);
    }
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibView commands
    
    
    LRESULT CDibView::OnDoRealize(WPARAM wParam, LPARAM)
    {
        ASSERT(wParam != NULL);
        CDibDoc* pDoc = GetDocument();
        if (pDoc->GetHDIB() == NULL)
            return 0L;  // must be a new document
    
        CPalette* pPal = pDoc->GetDocPalette();
        if (pPal != NULL)
        {
            CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
            ASSERT_KINDOF(CMainFrame, pAppFrame);
    
            CClientDC appDC(pAppFrame);
            // All views but one should be a background palette.
            // wParam contains a handle to the active view, so the SelectPalette
            // bForceBackground flag is FALSE only if wParam == m_hWnd (this view)
            CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd);
    
            if (oldPalette != NULL)
            {
                UINT nColorsChanged = appDC.RealizePalette();
                if (nColorsChanged > 0)
                    pDoc->UpdateAllViews(NULL);
                appDC.SelectPalette(oldPalette, TRUE);
            }
            else
            {
                TRACE0("\tSelectPalette failed in CDibView::OnPaletteChanged\n");
            }
        }
    
        return 0L;
    }
    
    void CDibView::OnInitialUpdate()
    {
        CScrollView::OnInitialUpdate();
        ASSERT(GetDocument() != NULL);
    
        SetScrollSizes(MM_TEXT, GetDocument()->GetDocSize());
    }
    
    
    void CDibView::OnActivateView(BOOL bActivate, CView* pActivateView,
                        CView* pDeactiveView)
    {
        CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView);
    
        if (bActivate)
        {
            ASSERT(pActivateView == this);
            OnDoRealize((WPARAM)m_hWnd, 0);   // same as SendMessage(WM_DOREALIZE);
        }
    }
    
    void CDibView::OnEditCopy()
    {
        CDibDoc* pDoc = GetDocument();
        // Clean clipboard of contents, and copy the DIB.
    
        if (OpenClipboard())
        {
            BeginWaitCursor();
            EmptyClipboard();
            SetClipboardData (CF_DIB, CopyHandle((HANDLE) pDoc->GetHDIB()) );
            CloseClipboard();
            EndWaitCursor();
        }
    }
    
    
    
    void CDibView::OnUpdateEditCopy(CCmdUI* pCmdUI)
    {
        pCmdUI->Enable(GetDocument()->GetHDIB() != NULL);
    }
    
    
    void CDibView::OnEditPaste()
    {
        HDIB hNewDIB = NULL;
    
        if (OpenClipboard())
        {
            BeginWaitCursor();
    
            hNewDIB = (HDIB) CopyHandle(::GetClipboardData(CF_DIB));
    
            CloseClipboard();
    
            if (hNewDIB != NULL)
            {
                CDibDoc* pDoc = GetDocument();
                pDoc->ReplaceHDIB(hNewDIB); // and free the old DIB
                pDoc->InitDIBData();    // set up new size & palette
                pDoc->SetModifiedFlag(TRUE);
    
                SetScrollSizes(MM_TEXT, pDoc->GetDocSize());
                OnDoRealize((WPARAM)m_hWnd,0);  // realize the new palette
                pDoc->UpdateAllViews(NULL);
            }
            EndWaitCursor();
        }
    }
    
    
    void CDibView::OnUpdateEditPaste(CCmdUI* pCmdUI)
    {
        pCmdUI->Enable(::IsClipboardFormatAvailable(CF_DIB));
    }
    
    void CDibView::OperationOnCopy(pfnCDibDoc op)
    {
        BeginWaitCursor();
    
        CDibDoc* pDoc = GetDocument();
        CDibDoc* pDst = (CDibDoc*)((CDibLookApp*)AfxGetApp())->m_imageTemplate->OpenDocumentFile(NULL);    
    
        HDIB hNewDIB = (HDIB) CopyHandle((HANDLE) pDoc->GetHDIB()) ;
        if (hNewDIB != NULL)
        {
            pDst->ReplaceHDIB(hNewDIB); // and free the old DIB
            this->EnableScrollBar(SB_BOTH); //my attempt at forcing scrollbars
            (pDst->*op)(this) ;            // CPOO tu operacja
            POSITION pos = pDst->GetFirstViewPosition();
            pDst->GetNextView(pos)->EnableScrollBar(SB_BOTH);//my attempt at forcing scrollbars
            pDst->InitDIBData();    // set up new size & palette
            pDst->SetModifiedFlag(TRUE);
            SetScrollSizes(MM_TEXT, pDst->GetDocSize());  //this nothing change
            OnDoRealize((WPARAM)m_hWnd,0);  // realize the new palette
            pDst->UpdateAllViews(NULL);
        }
        EndWaitCursor();
    }
    void CDibView::OnGray() 
    {
        OperationOnCopy(&CDibDoc::ConvertToGrayImage) ;
    }
    
    dibdoc.cpp (void CDibDoc::ConvertToGrayImage(CView *view) is operation performed on image):

    Code:
    #include "stdafx.h"
    #include "diblook.h"
    #include <limits.h>
    #include <string.h>
    
    #include "dibdoc.h"
    #include "dibview.h"
    #include "outDoc.h"
    #include "afxext.h"
    #include <cmath>
    #ifdef _DEBUG
    #undef THIS_FILE
    static char BASED_CODE THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibDoc
    
    IMPLEMENT_DYNCREATE(CDibDoc, CDocument)
    
        BEGIN_MESSAGE_MAP(CDibDoc, CDocument)
            //{{AFX_MSG_MAP(CDibDoc)
            //}}AFX_MSG_MAP
        END_MESSAGE_MAP()
    
        /////////////////////////////////////////////////////////////////////////////
        // CDibDoc construction/destruction
    
        int CDibDoc::m_size = 8;
    
        CDibDoc::CDibDoc()
        {
            m_hDIB = NULL;
            m_palDIB = NULL;
            m_sizeDoc = CSize(1,1);     // dummy value to make CScrollView happy
            m_outputView = NULL ;
        }
    
        CDibDoc::~CDibDoc()
        {
            if (m_hDIB != NULL)
            {
                ::GlobalFree((HGLOBAL) m_hDIB);
            }
            if (m_palDIB != NULL)
            {
                delete m_palDIB;
            }
        }
    
        BOOL CDibDoc::OnNewDocument()
        {
            if (!CDocument::OnNewDocument())
                return FALSE;
            return TRUE;
        }
    
        void CDibDoc::InitDIBData()
        {
            if (m_palDIB != NULL)
            {
                delete m_palDIB;
                m_palDIB = NULL;
            }
            if (m_hDIB == NULL)
            {
                return;
            }
            // Set up document size
            LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
            if (::DIBWidth(lpDIB) > INT_MAX ||::DIBHeight(lpDIB) > INT_MAX)
            {
                ::GlobalUnlock((HGLOBAL) m_hDIB);
                ::GlobalFree((HGLOBAL) m_hDIB);
                m_hDIB = NULL;
                CString strMsg;
                strMsg.LoadString(IDS_DIB_TOO_BIG);
                MessageBox(NULL, strMsg, NULL, MB_ICONINFORMATION | MB_OK);
                return;
            }
            m_sizeDoc = CSize((int) ::DIBWidth(lpDIB), (int) ::DIBHeight(lpDIB));
            ::GlobalUnlock((HGLOBAL) m_hDIB);
            // Create copy of palette
            m_palDIB = new CPalette;
            if (m_palDIB == NULL)
            {
                // we must be really low on memory
                ::GlobalFree((HGLOBAL) m_hDIB);
                m_hDIB = NULL;
                return;
            }
            if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL)
            {
                // DIB may not have a palette
                delete m_palDIB;
                m_palDIB = NULL;
                return;
            }
        }
    
    
        BOOL CDibDoc::OnOpenDocument(LPCTSTR lpszPathName)
        {
            CFile file;
            CFileException fe;
            if (!file.Open(lpszPathName, CFile::modeRead |
                CFile::shareDenyWrite, &fe))
            {
                ReportSaveLoadException(lpszPathName, &fe,
                    FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
                return FALSE;
            }
    
            DeleteContents();
            BeginWaitCursor();
    
            // replace calls to Serialize with ReadDIBFile function
            TRY
            {
                m_hDIB = ::ReadDIBFile(file);
            }
            CATCH (CFileException, eLoad)
            {
                file.Abort(); // will not throw an exception
                EndWaitCursor();
                ReportSaveLoadException(lpszPathName, eLoad,
                    FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
                m_hDIB = NULL;
                return FALSE;
            }
            END_CATCH
    
                InitDIBData();
            EndWaitCursor();
    
            if (m_hDIB == NULL)
            {
                // may not be DIB format
                CString strMsg;
                strMsg.LoadString(IDS_CANNOT_LOAD_DIB);
                MessageBox(NULL, strMsg, NULL, MB_ICONINFORMATION | MB_OK);
                return FALSE;
            }
            SetPathName(lpszPathName);
            SetModifiedFlag(FALSE);     // start off with unmodified
            return TRUE;
        }
    
    
        BOOL CDibDoc::OnSaveDocument(LPCTSTR lpszPathName)
        {
            CFile file;
            CFileException fe;
    
            if (!file.Open(lpszPathName, CFile::modeCreate |
                CFile::modeReadWrite | CFile::shareExclusive, &fe))
            {
                ReportSaveLoadException(lpszPathName, &fe,
                    TRUE, AFX_IDP_INVALID_FILENAME);
                return FALSE;
            }
    
            // replace calls to Serialize with SaveDIB function
            BOOL bSuccess = FALSE;
            TRY
            {
                BeginWaitCursor();
                bSuccess = ::SaveDIB(m_hDIB, file);
                file.Close();
            }
            CATCH (CException, eSave)
            {
                file.Abort(); // will not throw an exception
                EndWaitCursor();
                ReportSaveLoadException(lpszPathName, eSave,
                    TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
                return FALSE;
            }
            END_CATCH
    
                EndWaitCursor();
            SetModifiedFlag(FALSE);     // back to unmodified
    
            if (!bSuccess)
            {
                // may be other-style DIB (load supported but not save)
                //  or other problem in SaveDIB
                CString strMsg;
                strMsg.LoadString(IDS_CANNOT_SAVE_DIB);
                MessageBox(NULL, strMsg, NULL, MB_ICONINFORMATION | MB_OK);
            }
    
            return bSuccess;
        }
    
        void CDibDoc::ReplaceHDIB(HDIB hDIB)
        {
            if (m_hDIB != NULL)
            {
                ::GlobalFree((HGLOBAL) m_hDIB);
            }
            m_hDIB = hDIB;
        }
    
        /////////////////////////////////////////////////////////////////////////////
        // CDibDoc diagnostics
    
    #ifdef _DEBUG
        void CDibDoc::AssertValid() const
        {
            CDocument::AssertValid();
        }
    
        void CDibDoc::Dump(CDumpContext& dc) const
        {
            CDocument::Dump(dc);
        }
    
    #endif //_DEBUG
    
        /////////////////////////////////////////////////////////////////////////////
        // CDibDoc commands
    
        void CDibDoc::ConvertToGrayImage(CView *view) //Rozpoznaje literę M z loga MODECOM
        {
            view->EnableScrollBar(SB_BOTH); //my attempt at forcing scrollbars
            RGBTRIPLE* rows[50000] ;
            int width, height ;
            if (GetDIBRowsRGB(m_hDIB,rows,&width,&height))
            {
                for (int x=0;x<width;x++)
                {
                    for (int y=0;y<height;y++)
                    {
                        int gray = rows[y][x].rgbtBlue+rows[y][x].rgbtRed+rows[y][x].rgbtGreen;
                        if (gray < 500)
                        {
                            rows[y][x].rgbtBlue = 0;
                            rows[y][x].rgbtRed = 0;
                            rows[y][x].rgbtGreen = 0;
                        }
                        else
                        {
                            rows[y][x].rgbtBlue = 255;
                            rows[y][x].rgbtRed = 255;
                            rows[y][x].rgbtGreen = 255;
                        }
                    }
                }
            FreeDIBRows(m_hDIB);
            }
            UpdateAllViews(NULL);
        }
    diblook.cpp:

    Code:
    #include "stdafx.h"
    #include "diblook.h"
    
    #include "mainfrm.h"
    #include "dibdoc.h"
    #include "dibview.h"
    
    #include "outdoc.h"
    
    #ifdef _DEBUG
    #undef THIS_FILE
    static char BASED_CODE THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibLookApp
    
    BEGIN_MESSAGE_MAP(CDibLookApp, CWinApp)
        //{{AFX_MSG_MAP(CDibLookApp)
        ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
        //}}AFX_MSG_MAP
        // Standard file based document commands
        ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
        ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
        // Standard print setup command
        ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibLookApp construction
    // Place all significant initialization in InitInstance
    
    CDibLookApp::CDibLookApp()
    {
    }
    
    /////////////////////////////////////////////////////////////////////////////
    // The one and only CDibLookApp object
    
    CDibLookApp NEAR theApp;
    
    /////////////////////////////////////////////////////////////////////////////
    // CDibLookApp initialization
    
    BOOL CDibLookApp::InitInstance()
    {
        // Standard initialization
        //  (if you are not using these features and wish to reduce the size
        // of your final executable, you should remove the following initialization
    
        Enable3dControls();     // Use 3d controls in dialogs
        LoadStdProfileSettings();  // Load standard INI file options (including MRU)
    
        // Register document templates which serve as connection between
        //  documents and views.  Views are contained in the specified view
    
        m_imageTemplate = new CMultiDocTemplate(IDR_DIBTYPE,
                RUNTIME_CLASS(CDibDoc),
                RUNTIME_CLASS(CMDIChildWnd),        // standard MDI child frame
                RUNTIME_CLASS(CDibView)) ;
        AddDocTemplate(m_imageTemplate);
    
        m_outputTemplate = new CMultiDocTemplate(IDR_TEXTTYPE,
            RUNTIME_CLASS(COutputDoc), RUNTIME_CLASS(CMDIChildWnd),
            RUNTIME_CLASS(CEditView)) ;
        //AddDocTemplate(m_outputTemplate);
    
    
        // create main MDI Frame window
        CMainFrame* pMainFrame = new CMainFrame;
        if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
            return FALSE;
        pMainFrame->ShowWindow(m_nCmdShow);
        pMainFrame->UpdateWindow();
        m_pMainWnd = pMainFrame;
    
        // enable file manager drag/drop and DDE Execute open
        m_pMainWnd->DragAcceptFiles();
    
        EnableShellOpen();
        RegisterShellFileTypes(TRUE);
    
        // Parse command line for standard shell commands, DDE, file open
        CCommandLineInfo cmdInfo;
        cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing ;
        ParseCommandLine(cmdInfo);
    
        // Dispatch commands specified on the command line
        if (!ProcessShellCommand(cmdInfo))
            return FALSE;
    
        return TRUE;
    }
    
    
    /////////////////////////////////////////////////////////////////////////////
    // CAboutDlg dialog used for App About
    
    class CAboutDlg : public CDialog
    {
    public:
        CAboutDlg() : CDialog(CAboutDlg::IDD)
            {
                //{{AFX_DATA_INIT(CAboutDlg)
                //}}AFX_DATA_INIT
            }
    
    // Dialog Data
        //{{AFX_DATA(CAboutDlg)
            enum { IDD = IDD_ABOUTBOX };
        //}}AFX_DATA
    
    // Implementation
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        //{{AFX_MSG(CAboutDlg)
            // No message handlers
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };
    
    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()
    mainfrm.cpp:

    Code:
    #include "stdafx.h"
    #include "diblook.h"
    
    #include "mainfrm.h"
    
    #ifdef _DEBUG
    #undef THIS_FILE
    static char BASED_CODE THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CMainFrame
    
    IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
    
    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
        //{{AFX_MSG_MAP(CMainFrame)
        ON_WM_CREATE()
        ON_WM_PALETTECHANGED()
        ON_WM_QUERYNEWPALETTE()
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // arrays of IDs used to initialize control bars
    
    // toolbar buttons - IDs are command buttons
    static UINT BASED_CODE buttons[] =
    {
        // same order as in the bitmap 'toolbar.bmp'
        ID_FILE_NEW,
        ID_FILE_OPEN,
        ID_FILE_SAVE,
            ID_SEPARATOR,
        ID_EDIT_CUT,
        ID_EDIT_COPY,
        ID_EDIT_PASTE,
            ID_SEPARATOR,
        ID_FILE_PRINT,
        ID_APP_ABOUT,
    };
    
    static UINT BASED_CODE indicators[] =
    {
        ID_SEPARATOR,           // status line indicator
        ID_INDICATOR_CAPS,
        ID_INDICATOR_NUM,
        ID_INDICATOR_SCRL,
    };
    
    /////////////////////////////////////////////////////////////////////////////
    // CMainFrame construction/destruction
    
    CMainFrame::CMainFrame()
    {
    }
    
    CMainFrame::~CMainFrame()
    {
    }
    
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
    
        if (!m_wndToolBar.Create(this) ||
            !m_wndToolBar.LoadBitmap(IDR_MAINFRAME) ||
            !m_wndToolBar.SetButtons(buttons,
              sizeof(buttons)/sizeof(UINT)))
        {
            TRACE0("Failed to create toolbar\n");
            return -1;      // fail to create
        }
    
        if (!m_wndStatusBar.Create(this) ||
            !m_wndStatusBar.SetIndicators(indicators,
              sizeof(indicators)/sizeof(UINT)))
        {
            TRACE0("Failed to create status bar\n");
            return -1;      // fail to create
        }
    
        return 0;
    }
    
    
    /////////////////////////////////////////////////////////////////////////////
    // CMainFrame commands
    
    
    void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd)
    {
        CMDIFrameWnd::OnPaletteChanged(pFocusWnd);
    
        // always realize the palette for the active view
        CMDIChildWnd* pMDIChildWnd = MDIGetActive();
        if (pMDIChildWnd == NULL)
            return; // no active MDI child frame
        CView* pView = pMDIChildWnd->GetActiveView();
        ASSERT(pView != NULL);
        pView->EnableScrollBar(SB_BOTH);
        // notify all child windows that the palette has changed
        SendMessageToDescendants(WM_DOREALIZE, (WPARAM)pView->m_hWnd);
    }
    
    
    
    BOOL CMainFrame::OnQueryNewPalette()
    {
        // always realize the palette for the active view
        CMDIChildWnd* pMDIChildWnd = MDIGetActive();
        if (pMDIChildWnd == NULL)
            return FALSE; // no active MDI child frame (no new palette)
        CView* pView = pMDIChildWnd->GetActiveView();
        ASSERT(pView != NULL);
    
        // just notify the target view
        pView->SendMessage(WM_DOREALIZE, (WPARAM)pView->m_hWnd);
        return TRUE;
    }
    myfile.cpp:

    Code:
    #include "stdafx.h"
    #include <math.h>
    #include <io.h>
    #include <direct.h>
    #include "dibapi.h"
    
    /*
     * Dib Header Marker - used in writing DIBs to files
     */
    #define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')
    
    #ifdef _MAC
    #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
    #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
    void ByteSwapHeader(BITMAPFILEHEADER* bmiHeader);
    void ByteSwapInfo(LPSTR lpHeader, BOOL fWin30Header);
    #endif
    
    /*************************************************************************
     *
     * SaveDIB()
     *
     * Saves the specified DIB into the specified CFile.  The CFile
     * is opened and closed by the caller.
     *
     * Parameters:
     *
     * HDIB hDib - Handle to the dib to save
     *
     * CFile& file - open CFile used to save DIB
     *
     * Return value: TRUE if successful, else FALSE or CFileException
     *
     *************************************************************************/
    
    
    BOOL WINAPI SaveDIB(HDIB hDib, CFile& file)
    {
        BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
        LPBITMAPINFOHEADER lpBI;   // Pointer to DIB info structure
        DWORD dwDIBSize;
    
        if (hDib == NULL)
            return FALSE;
    
        /*
         * Get a pointer to the DIB memory, the first of which contains
         * a BITMAPINFO structure
         */
        lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
        if (lpBI == NULL)
            return FALSE;
    
        if (!IS_WIN30_DIB(lpBI))
        {
            ::GlobalUnlock((HGLOBAL) hDib);
            return FALSE;       // It's an other-style DIB (save not supported)
        }
    
        /*
         * Fill in the fields of the file header
         */
    
        /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
        bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM"
    
        // Calculating the size of the DIB is a bit tricky (if we want to
        // do it right).  The easiest way to do this is to call GlobalSize()
        // on our global handle, but since the size of our global memory may have
        // been padded a few bytes, we may end up writing out a few too
        // many bytes to the file (which may cause problems with some apps).
        //
        // So, instead let's calculate the size manually (if we can)
        //
        // First, find size of header plus size of color table.  Since the
        // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
        // the size of the structure, let's use this.
    
        dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI);  // Partial Calculation
    
        // Now calculate the size of the image
    
        if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
        {
            // It's an RLE bitmap, we can't calculate size, so trust the
            // biSizeImage field
    
            dwDIBSize += lpBI->biSizeImage;
        }
        else
        {
            DWORD dwBmBitsSize;  // Size of Bitmap Bits only
    
            // It's not RLE, so size is Width (DWORD aligned) * Height
    
            dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
    
            dwDIBSize += dwBmBitsSize;
    
            // Now, since we have calculated the correct size, why don't we
            // fill in the biSizeImage field (this will fix any .BMP files which
            // have this field incorrect).
    
            lpBI->biSizeImage = dwBmBitsSize;
        }
    
    
        // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
    
        bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
        bmfHdr.bfReserved1 = 0;
        bmfHdr.bfReserved2 = 0;
    
        /*
         * Now, calculate the offset the actual bitmap bits will be in
         * the file -- It's the Bitmap file header plus the DIB header,
         * plus the size of the color table.
         */
        bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
                                                  + PaletteSize((LPSTR)lpBI);
    #ifdef _MAC
        ByteSwapHeader(&bmfHdr);
    
        // First swap the size field
        *((LPDWORD)lpBI) = SWAPLONG(*((LPDWORD)lpBI));
    
        // Now swap the rest of the structure (we don't save < Win30 files)
        ByteSwapInfo((LPSTR)lpBI, TRUE);
    #endif
    
        TRY
        {
            // Write the file header
            file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
            //
            // Write the DIB header and the bits
            //
            file.Write(lpBI, dwDIBSize);
        }
        CATCH (CFileException, e)
        {
    #ifdef _MAC
            // Swap everything back
            *((LPDWORD)lpBI) = SWAPLONG(*((LPDWORD)lpBI));
            ByteSwapInfo((LPSTR)lpBI, TRUE);
    #endif
            ::GlobalUnlock((HGLOBAL) hDib);
            THROW_LAST();
        }
        END_CATCH
    
    #ifdef _MAC
        // Swap everything back
        *((LPDWORD)lpBI) = SWAPLONG(*((LPDWORD)lpBI));
        ByteSwapInfo((LPSTR)lpBI, TRUE);
    #endif
    
        ::GlobalUnlock((HGLOBAL) hDib);
        return TRUE;
    }
    
    
    /*************************************************************************
    
      Function:  ReadDIBFile (CFile&)
    
       Purpose:  Reads in the specified DIB file into a global chunk of
                 memory.
    
       Returns:  A handle to a dib (hDIB) if successful.
                 NULL if an error occurs.
    
      Comments:  BITMAPFILEHEADER is stripped off of the DIB.  Everything
                 from the end of the BITMAPFILEHEADER structure on is
                 returned in the global memory handle.
    
    *************************************************************************/
    
    
    HDIB WINAPI ReadDIBFile(CFile& file)
    {
        BITMAPFILEHEADER bmfHeader;
        DWORD dwBitsSize;
        HDIB hDIB;
        LPSTR pDIB;
    
        /*
         * get length of DIB in bytes for use when reading
         */
    
        dwBitsSize = file.GetLength();
    
        /*
         * Go read the DIB file header and check if it's valid.
         */
        if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
            return NULL;
    
    #ifdef _MAC
        ByteSwapHeader(&bmfHeader);
    #endif
        if (bmfHeader.bfType != DIB_HEADER_MARKER)
            return NULL;
    
        /*
         * Allocate memory for DIB
         */
        hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
        if (hDIB == 0)
        {
            return NULL;
        }
        pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
    
        /*
         * Go read the bits.
         */
        if (file.Read(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
            dwBitsSize - sizeof(BITMAPFILEHEADER) )
        {
            ::GlobalUnlock((HGLOBAL) hDIB);
            ::GlobalFree((HGLOBAL) hDIB);
            return NULL;
        }
    #ifdef _MAC
        // First swap the size field
        *((LPDWORD)pDIB) = SWAPLONG(*((LPDWORD)pDIB));
    
        // Now swap the rest of the structure
        ByteSwapInfo(pDIB, IS_WIN30_DIB(pDIB));
    #endif
        ::GlobalUnlock((HGLOBAL) hDIB);
        return hDIB;
    }
    
    
    #ifdef _MAC
    void ByteSwapHeader(BITMAPFILEHEADER* bmfHeader)
    {
        bmfHeader->bfType = SWAPWORD(bmfHeader->bfType);
        bmfHeader->bfSize = SWAPLONG(bmfHeader->bfSize);
        bmfHeader->bfOffBits = SWAPLONG(bmfHeader->bfOffBits);
    }
    
    
    void ByteSwapInfo(LPSTR lpHeader, BOOL fWin30Header)
    {
        // Note this doesn't swap the bcSize/biSize field.  It assumes that the
        // size field was swapped during read or while setting the fWin30Header
        // flag.
    
        if (fWin30Header)
        {
            LPBITMAPINFOHEADER lpBMIH = &(LPBITMAPINFO(lpHeader)->bmiHeader);
    
            //lpBMIH->biSize = SWAPLONG(lpBMIH->biSize);
            lpBMIH->biWidth = SWAPLONG(lpBMIH->biWidth);
            lpBMIH->biHeight = SWAPLONG(lpBMIH->biHeight);
            lpBMIH->biPlanes = SWAPWORD(lpBMIH->biPlanes);
            lpBMIH->biBitCount = SWAPWORD(lpBMIH->biBitCount);
            lpBMIH->biCompression = SWAPLONG(lpBMIH->biCompression);
            lpBMIH->biSizeImage = SWAPLONG(lpBMIH->biSizeImage);
            lpBMIH->biXPelsPerMeter = SWAPLONG(lpBMIH->biXPelsPerMeter);
            lpBMIH->biYPelsPerMeter = SWAPLONG(lpBMIH->biYPelsPerMeter);
            lpBMIH->biClrUsed = SWAPLONG(lpBMIH->biClrUsed);
            lpBMIH->biClrImportant = SWAPLONG(lpBMIH->biClrImportant);
        }
        else
        {
            LPBITMAPCOREHEADER lpBMCH = &(LPBITMAPCOREINFO(lpHeader)->bmciHeader);
    
            lpBMCH->bcWidth = SWAPWORD(lpBMCH->bcWidth);
            lpBMCH->bcHeight = SWAPWORD(lpBMCH->bcHeight);
            lpBMCH->bcPlanes = SWAPWORD(lpBMCH->bcPlanes);
            lpBMCH->bcBitCount = SWAPWORD(lpBMCH->bcBitCount);
        }
    }
    
    #endif
    
    
    BOOL WINAPI FreeDIBRows(HDIB hDib) {
        ::GlobalUnlock((HGLOBAL) hDib);
        return TRUE ;
    }
    
    
    /*************************************************************************
     *
     * SaveDIB()
     *
     * Saves the specified DIB into the specified CFile.  The CFile
     * is opened and closed by the caller.
     *
     * Parameters:
     *
     * HDIB hDib - Handle to the dib to save
     *
     * CFile& file - open CFile used to save DIB
     *
     * Return value: TRUE if successful, else FALSE or CFileException
     *
     *************************************************************************/
    
    BOOL WINAPI GetDIBRowsRGB(HDIB hDib, RGBTRIPLE* rows[], int *Width, int *Height)
    {
        BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
        LPBITMAPINFOHEADER lpBI;   // Pointer to DIB info structure
        DWORD dwDIBSize;
    
        if (hDib == NULL)
            return FALSE;
    
        /*
         * Get a pointer to the DIB memory, the first of which contains
         * a BITMAPINFO structure
         */
        lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
        if (lpBI == NULL)
            return FALSE;
    
        if (!IS_WIN30_DIB(lpBI))
        {
            ::GlobalUnlock((HGLOBAL) hDib);
            return FALSE;       // It's an other-style DIB (save not supported)
        }
    
        /*
         * Fill in the fields of the file header
         */
    
        /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
        bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM"
    
        // Calculating the size of the DIB is a bit tricky (if we want to
        // do it right).  The easiest way to do this is to call GlobalSize()
        // on our global handle, but since the size of our global memory may have
        // been padded a few bytes, we may end up writing out a few too
        // many bytes to the file (which may cause problems with some apps).
        //
        // So, instead let's calculate the size manually (if we can)
        //
        // First, find size of header plus size of color table.  Since the
        // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
        // the size of the structure, let's use this.
    
        dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI);  // Partial Calculation
        LPSTR lpStr ;
        lpStr = (LPSTR)lpBI ;
        
        lpStr = lpStr+dwDIBSize ;
    
        // Now calculate the size of the image
    
        if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
        {
            // It's an RLE bitmap, we can't calculate size, so trust the
            // biSizeImage field
    
            dwDIBSize += lpBI->biSizeImage;
        }
        else
        {
            DWORD dwBmBitsSize;  // Size of Bitmap Bits only
    
            // It's not RLE, so size is Width (DWORD aligned) * Height
    
            dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
    
            dwDIBSize += dwBmBitsSize;
    
            // Now, since we have calculated the correct size, why don't we
            // fill in the biSizeImage field (this will fix any .BMP files which
            // have this field incorrect).
    
            lpBI->biSizeImage = dwBmBitsSize;
        }
    
    
        // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
    
        bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
        bmfHdr.bfReserved1 = 0;
        bmfHdr.bfReserved2 = 0;
    
        /*
         * Now, calculate the offset the actual bitmap bits will be in
         * the file -- It's the Bitmap file header plus the DIB header,
         * plus the size of the color table.
         */
        bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
                                                  + PaletteSize((LPSTR)lpBI);
        
    
        rows[0] = (RGBTRIPLE*)lpStr ;
        for(int i=1;i<lpBI->biHeight;i++)
            // >> Poprawka A. Wujek
            // rows[i] = rows[i-1]+lpBI->biWidth ;  << było
            if(lpBI->biWidth%4==0)
                rows[i] = rows[i-1]+lpBI->biWidth;
            else
                rows[i] = (RGBTRIPLE*)((BYTE*)(rows[i-1]+lpBI->biWidth)+4-(lpBI->biWidth*3)%4) ;
           // << Poprawka A. Wujek
        if( Width != NULL )
            *Width = lpBI->biWidth ;
        if( Height != NULL )
            *Height = lpBI->biHeight ;
    
        return TRUE;
    }
    
    OutputDoc.cpp:

    Code:
    #include "stdafx.h"
    #include "diblook.h"
    #include "OutDoc.h"
    #include "afxext.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // COutputDoc
    
    IMPLEMENT_DYNCREATE(COutputDoc, CDocument)
    
    COutputDoc::COutputDoc()
    {
    }
    
    BOOL COutputDoc::OnNewDocument()
    {
        if (!CDocument::OnNewDocument())
            return FALSE;
        return TRUE;
    }
    
    COutputDoc::~COutputDoc()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(COutputDoc, CDocument)
        //{{AFX_MSG_MAP(COutputDoc)
            // NOTE - the ClassWizard will add and remove mapping macros here.
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // COutputDoc diagnostics
    
    #ifdef _DEBUG
    void COutputDoc::AssertValid() const
    {
        CDocument::AssertValid();
    }
    
    void COutputDoc::Dump(CDumpContext& dc) const
    {
        CDocument::Dump(dc);
    }
    #endif //_DEBUG
    
    /////////////////////////////////////////////////////////////////////////////
    // COutputDoc serialization
    
    void COutputDoc::Serialize(CArchive& ar)
    {
        ((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
        if (ar.IsStoring())
        {
            // TODO: add storing code here
        }
        else
        {
            // TODO: add loading code here
        }
    }
    
    /////////////////////////////////////////////////////////////////////////////
    // COutputDoc commands
    
     

Share This Page