From 7bdff45316351eed4af0a7cd152c350824648159 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 16 Apr 2000 00:19:37 +0000 Subject: [PATCH] 1. fixed assert failure/crash when clicking in empty checklistboxes 2. wrote wxBMPHandler::SaveFile() 3. fixed stupid bug in handling DDE commands in wxMimeTypesManager git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_2_BRANCH@7181 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/imagbmp.h | 26 +++--- src/common/imagbmp.cpp | 166 ++++++++++++++++++++++++++++++++++++ src/msw/listbox.cpp | 7 +- src/msw/mimetype.cpp | 4 +- src/xpm/xpm.dsp | 186 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 375 insertions(+), 14 deletions(-) create mode 100644 src/xpm/xpm.dsp diff --git a/include/wx/imagbmp.h b/include/wx/imagbmp.h index 8fc5d9a820..92086f76f6 100644 --- a/include/wx/imagbmp.h +++ b/include/wx/imagbmp.h @@ -16,28 +16,32 @@ #include "wx/image.h" -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxBMPHandler -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- -class WXDLLEXPORT wxBMPHandler: public wxImageHandler +class WXDLLEXPORT wxBMPHandler : public wxImageHandler { - DECLARE_DYNAMIC_CLASS(wxBMPHandler) - public: - - inline wxBMPHandler() + wxBMPHandler() { - m_name = "BMP file"; - m_extension = "bmp"; + m_name = _T("BMP file"); + m_extension = _T("bmp"); m_type = wxBITMAP_TYPE_BMP; - m_mime = "image/bmp"; + m_mime = _T("image/bmp"); }; + // saving bitmaps is Windows-only +#ifdef __WIN32__ + virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=TRUE ); +#endif // __WIN32__ + #if wxUSE_STREAMS virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=TRUE, int index=0 ); virtual bool DoCanRead( wxInputStream& stream ); -#endif +#endif // wxUSE_STREAMS + + DECLARE_DYNAMIC_CLASS(wxBMPHandler) }; diff --git a/src/common/imagbmp.cpp b/src/common/imagbmp.cpp index 45169259e1..71a6665ec4 100644 --- a/src/common/imagbmp.cpp +++ b/src/common/imagbmp.cpp @@ -47,6 +47,172 @@ IMPLEMENT_DYNAMIC_CLASS(wxBMPHandler,wxImageHandler) +#ifdef __WIN32__ + +#include + +static void OutOfMemory(size_t nBytesNeeded) +{ + wxLogError(_("Failed to allocate %u bytes of memory."), nBytesNeeded); +} + +// VZ: I'm not an expert in bitmaps, this is a quick and dirty C function I +// wrote some time ago and it probably doesn't deal properly with all +// bitmaps - any corrections/improvements are more than welcome. +bool wxBMPHandler::SaveFile(wxImage *image, + wxOutputStream& stream, + bool verbose) +{ + // get HBITMAP first + wxCHECK_MSG( image, FALSE, _T("invalid pointer in wxBMPHandler::SaveFile") ); + + wxBitmap bitmap = image->ConvertToBitmap(); + HBITMAP hBmp = GetHbitmapOf(bitmap); + wxCHECK_MSG( hBmp, FALSE, _T("can't save invalid bitmap") ); + + // actual C code starts here + BITMAPFILEHEADER hdr; + BITMAPINFOHEADER *pbih; + BITMAP bmp; + WORD nClrBits; + size_t sizeOfBmi, sizeColTable; + BITMAPINFO *pbmi = NULL; + void *bmpData = NULL; + HDC hdc = NULL; + int rc = 0; + + /* + create and initialize BITMAPINFO + */ + + /* get the number of bitmap colours and its size */ + if ( !GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp) ) { + wxLogLastError(_T("GetObject")); + + goto cleanup; + } + + /* calc the number of colour bits needed */ + nClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); + if ( nClrBits == 1 ) nClrBits = 1; + else if ( nClrBits <= 4 ) nClrBits = 4; + else if ( nClrBits <= 8 ) nClrBits = 8; + else if ( nClrBits <= 16 ) nClrBits = 16; + else if ( nClrBits <= 24 ) nClrBits = 24; + else nClrBits = 32; + + /* alloc memory knowing that all bitmaps except 24bpp need extra RGBQUAD + * table */ + sizeOfBmi = sizeof(BITMAPINFOHEADER); + if ( nClrBits != 24 ) + sizeOfBmi += sizeof(RGBQUAD) * ( 1 << nClrBits); + + pbmi = (BITMAPINFO *)calloc(sizeOfBmi, 1); + if ( !pbmi ) { + OutOfMemory(sizeOfBmi); + + goto cleanup; + } + + /* initialize the fields in the BITMAPINFO structure */ + pbih = (BITMAPINFOHEADER *)pbmi; + pbih->biSize = sizeof(BITMAPINFOHEADER); + pbih->biWidth = bmp.bmWidth; + pbih->biHeight = bmp.bmHeight; + pbih->biPlanes = bmp.bmPlanes; + pbih->biBitCount = bmp.bmBitsPixel; + if ( nClrBits < 24 ) + pbih->biClrUsed = 1 << nClrBits; + pbih->biCompression = BI_RGB; + pbih->biSizeImage = 0; + pbih->biClrImportant = 0; + + /* let GetDIBits fill the size field, calc it ourselves if it didn't */ + hdc = CreateCompatibleDC(NULL); + if ( !hdc ) { + wxLogLastError(_T("CreateCompatibleDC(NULL)")); + + goto cleanup; + } + + (void)GetDIBits(hdc, hBmp, 0, pbih->biHeight, NULL, pbmi, DIB_RGB_COLORS); + if ( !pbih->biSizeImage ) + pbih->biSizeImage = (pbih->biWidth + 15) / 16 * pbih->biHeight * nClrBits; + + /* + get the data from the bitmap + */ + bmpData = malloc(pbih->biSizeImage); + if ( !bmpData ) { + OutOfMemory(pbih->biSizeImage); + + goto cleanup; + } + + if ( !GetDIBits(hdc, hBmp, + 0, pbih->biHeight, + bmpData, pbmi, DIB_RGB_COLORS) ) { + wxLogLastError(_T("GetDIBits")); + + goto cleanup; + } + + /* + write the data to the file + */ + + /* write the file header */ + sizeColTable = pbih->biClrUsed * sizeof(RGBQUAD); + hdr.bfType = 0x4d42; /* "BM" string */ + hdr.bfSize = sizeof(BITMAPFILEHEADER) + + pbih->biSize + sizeColTable + pbih->biSizeImage; + hdr.bfReserved1 = 0; + hdr.bfReserved2 = 0; + hdr.bfOffBits = hdr.bfSize - pbih->biSizeImage; + + if ( !stream.Write(&hdr, sizeof(hdr)) ) { + if ( verbose ) + wxLogError(_("Couldn't write the BMP file header.")); + + goto cleanup; + } + + /* write the bitmap header to the file */ + if ( !stream.Write(pbih, sizeof(BITMAPINFOHEADER) + sizeColTable) ) { + if ( verbose ) + wxLogError(_("Couldn't write the bitmap header.")); + + goto cleanup; + } + + /* write the data to the file */ + if ( !stream.Write(bmpData, pbih->biSizeImage) ) { + if ( verbose ) + wxLogError(_("Couldn't write bitmap data.")); + + goto cleanup; + } + + /* success */ + rc = 1; + +cleanup: + free(bmpData); + free(pbmi); + if ( hdc ) + DeleteDC(hdc); + + if ( !rc ) { + wxLogError(_("Failed to save the bitmap.")); + + return FALSE; + } + + return TRUE; +} + +#endif // __WIN32__ + #if wxUSE_STREAMS #ifndef BI_RGB diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index d7bf6b4769..00f6e2d1d8 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -741,6 +741,11 @@ bool wxListBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE ); DRAWITEMSTRUCT *pStruct = (DRAWITEMSTRUCT *)item; + UINT itemID = pStruct->itemID; + + // the item may be -1 for an empty listbox + if ( itemID == (UINT)-1 ) + return FALSE; long data = ListBox_GetItemData(GetHwnd(), pStruct->itemID); @@ -751,7 +756,7 @@ bool wxListBox::MSWOnDraw(WXDRAWITEMSTRUCT *item) wxDC dc; dc.SetHDC((WXHDC)pStruct->hDC, FALSE); wxRect rect(wxPoint(pStruct->rcItem.left, pStruct->rcItem.top), - wxPoint(pStruct->rcItem.right, pStruct->rcItem.bottom)); + wxPoint(pStruct->rcItem.right, pStruct->rcItem.bottom)); return pItem->OnDrawItem(dc, rect, (wxOwnerDrawn::wxODAction)pStruct->itemAction, diff --git a/src/msw/mimetype.cpp b/src/msw/mimetype.cpp index a4e3d9d8a1..4ca0315ec2 100644 --- a/src/msw/mimetype.cpp +++ b/src/msw/mimetype.cpp @@ -117,7 +117,7 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const } } -#if wxUSE_DDE +#if wxUSE_IPC // look whether we must issue some DDE requests to the application // (and not just launch it) strKey += _T("\\DDEExec"); @@ -141,7 +141,7 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const << _T('#') << ddeCommand; } else -#endif // wxUSE_DDE +#endif // wxUSE_IPC if ( !foundFilename ) { // we didn't find any '%1' - the application doesn't know which // file to open (note that we only do it if there is no DDEExec diff --git a/src/xpm/xpm.dsp b/src/xpm/xpm.dsp new file mode 100644 index 0000000000..07451438e5 --- /dev/null +++ b/src/xpm/xpm.dsp @@ -0,0 +1,186 @@ +# Microsoft Developer Studio Project File - Name="xpm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=xpm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "xpm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "xpm.mak" CFG="xpm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "xpm - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "xpm - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "xpm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX- /O1 /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "xpm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "xpm___Win32_Debug" +# PROP BASE Intermediate_Dir "xpm___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX- /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "xpm - Win32 Release" +# Name "xpm - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\attrib.c +# End Source File +# Begin Source File + +SOURCE=.\crbuffri.c +# End Source File +# Begin Source File + +SOURCE=.\crdatfri.c +# End Source File +# Begin Source File + +SOURCE=.\create.c +# End Source File +# Begin Source File + +SOURCE=.\crifrbuf.c +# End Source File +# Begin Source File + +SOURCE=.\crifrdat.c +# End Source File +# Begin Source File + +SOURCE=.\dataxpm.c +# End Source File +# Begin Source File + +SOURCE=.\hashtab.c +# End Source File +# Begin Source File + +SOURCE=.\imagexpm.c +# End Source File +# Begin Source File + +SOURCE=.\info.c +# End Source File +# Begin Source File + +SOURCE=.\misc.c +# End Source File +# Begin Source File + +SOURCE=.\parse.c +# End Source File +# Begin Source File + +SOURCE=.\rdftodat.c +# End Source File +# Begin Source File + +SOURCE=.\rdftoi.c +# End Source File +# Begin Source File + +SOURCE=.\rgb.c +# End Source File +# Begin Source File + +SOURCE=.\scan.c +# End Source File +# Begin Source File + +SOURCE=.\simx.c +# End Source File +# Begin Source File + +SOURCE=.\wrffrdat.c +# End Source File +# Begin Source File + +SOURCE=.\wrffri.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\rgbtab.h +# End Source File +# Begin Source File + +SOURCE=.\simx.h +# End Source File +# Begin Source File + +SOURCE=.\xpm.h +# End Source File +# Begin Source File + +SOURCE=.\xpmi.h +# End Source File +# End Group +# End Target +# End Project