How to enable scrollbars in DIBLOOK result window topic posted under MFC Programming which is a part of Programming category in CFanatic Forum

12-19-2011, 08:50 PM
|
|
Junior Member
|
|
Join Date: Dec 2011
Location: Chotomów, Poland
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
How to enable scrollbars in DIBLOOK result window
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
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
All times are GMT -5. The time now is 03:36 PM.
|