More tweaks to wxMicroWi

More tweaks to MicroWindows


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13161 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2001-12-22 19:43:44 +00:00
parent a9249b2eb2
commit 62e1ba759a
12 changed files with 219 additions and 29 deletions

View File

@@ -1,6 +1,6 @@
src/jpeg/make* src/jpeg/make*
src/jpeg/JpegVC.dsp src/jpeg/jpeg.dsp
src/jpeg/JpegVC.dsw src/jpeg/jpeg.dsw
src/jpeg/*.c src/jpeg/*.c
src/jpeg/*.h src/jpeg/*.h
src/jpeg/README src/jpeg/README

View File

@@ -1,6 +1,6 @@
src/tiff/make* src/tiff/make*
src/tiff/TiffVC.dsp src/tiff/tiff.dsp
src/tiff/TiffVC.dsw src/tiff/tiff.dsw
src/tiff/*.c src/tiff/*.c
src/tiff/*.h src/tiff/*.h
src/tiff/README src/tiff/README

View File

@@ -108,6 +108,33 @@ is preferably to proliferating many #ifdefs in the
wxMSW/wxMicroWindows port itself. wxMSW/wxMicroWindows port itself.
Errors/warnings
===============
In file ../../src/msw/window.cpp at line 1294: 'UpdateWindow' failed with error 0x00000000 (Success).
- caused because there are no paint messages pending. Presumed
harmless.
In file ../../src/msw/dc.cpp at line 1838: 'BitBlt' failed with error 0x00000000 (Success).
- caused because the window isn't mapped, and MwPrepareDC in wingdi.c
fails (hwnd->unmapcount is non-zero). Presumed harmless.
Recursive paint problem, e.g. when clicking the 'Press Me!'
button in the widgets sample a few times, until the text control
is full.
- possibly the scrollbar is causing the text control to be
updated, which somehow effects the scrollbar, which causes
a window update, etc.
Sluggish updates.
- probably because many image to bitmap conversions are being
done on update, and bitmaps should probably be cached.
Things missing from MicroWindows that need to be worked around Things missing from MicroWindows that need to be worked around
============================================================== ==============================================================
@@ -136,13 +163,11 @@ So how can we convert from wxImage to wxBitmap in MicroWindows?
Well, a simple-minded way would be to use CreateCompatibleBitmap Well, a simple-minded way would be to use CreateCompatibleBitmap
which returns an HBITMAP, select it into an HDC, and draw which returns an HBITMAP, select it into an HDC, and draw
the pixels from the wxImage to the HDC one by one with SetPixel. the pixels from the wxImage to the HDC one by one with SetPixel.
This is now implemented, but without any mask handling, which will This is now implemented, but there are problems with masks.
be needed. (a) masks have to be created at screen depth because BitBlt/GrDraw
can't cope with differing depths, and (b) masked blitting
Unfortunately, there's a crash in malloc, within DeleteObject, when is still not working (try enabling mask creation in
passed a bitmap created by CreateCompatibleBitmap, but only after a few wxBitmap::CreateFromImage by setting USE_MASKS to 1).
deletions. This has yet to be tracked down, maybe by trying to create/delete
some wxBitmaps from XPMs, from within e.g. the minimal sample.
Other missing features Other missing features

View File

@@ -77,6 +77,8 @@ BOOL SetScrollInfo (HWND hWnd, int iSBar,
LPCSCROLLINFO lpsi, BOOL fRedraw); LPCSCROLLINFO lpsi, BOOL fRedraw);
BOOL GetScrollInfo(HWND hWnd, int iSBar, LPSCROLLINFO lpsi); BOOL GetScrollInfo(HWND hWnd, int iSBar, LPSCROLLINFO lpsi);
BOOL ShowScrollBar (HWND hWnd, int iSBar, BOOL bShow); BOOL ShowScrollBar (HWND hWnd, int iSBar, BOOL bShow);
HBITMAP WINAPI
CreateBitmap( int width, int height, int nPlanes, int bPP, LPCVOID lpData);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -50,7 +50,7 @@ LIBNAME =
include $(TOP)/Makefile.rules include $(TOP)/Makefile.rules
# List of objects to compile # List of objects to compile
OBJS = widgets.o button.o # combobox.o gauge.o listbox.o notebook.o radiobox.o # slider.o spinbtn.o \ OBJS = widgets.o button.o combobox.o gauge.o listbox.o notebook.o radiobox.o slider.o spinbtn.o \
static.o textctrl.o static.o textctrl.o
all: widgets all: widgets

View File

@@ -40,6 +40,8 @@
#include "wx/icon.h" #include "wx/icon.h"
#endif #endif
//#include "device.h"
#include "wx/msw/private.h" #include "wx/msw/private.h"
#include "wx/log.h" #include "wx/log.h"
@@ -89,10 +91,12 @@ void wxBitmapRefData::Free()
if ( m_hBitmap) if ( m_hBitmap)
{ {
// printf("About to delete bitmap %d\n", (int) (HBITMAP) m_hBitmap); // printf("About to delete bitmap %d\n", (int) (HBITMAP) m_hBitmap);
#if 1
if ( !::DeleteObject((HBITMAP)m_hBitmap) ) if ( !::DeleteObject((HBITMAP)m_hBitmap) )
{ {
wxLogLastError(wxT("DeleteObject(hbitmap)")); wxLogLastError(wxT("DeleteObject(hbitmap)"));
} }
#endif
} }
delete m_bitmapMask; delete m_bitmapMask;
@@ -381,17 +385,29 @@ bool wxBitmap::Create(int w, int h, int d)
bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
{ {
#ifdef __WXMICROWIN__ #ifdef __WXMICROWIN__
// Set this to 1 to experiment with mask code,
// which currently doesn't work
#define USE_MASKS 0
m_refData = new wxBitmapRefData(); m_refData = new wxBitmapRefData();
// Initial attempt at a simple-minded implementation. // Initial attempt at a simple-minded implementation.
// The bitmap will always be created at the screen depth, // The bitmap will always be created at the screen depth,
// so the 'depth' argument is ignored. // so the 'depth' argument is ignored.
// TODO: transparency (create a mask image)
HDC hScreenDC = ::GetDC(NULL); HDC hScreenDC = ::GetDC(NULL);
// printf("Screen planes = %d, bpp = %d\n", hScreenDC->psd->planes, hScreenDC->psd->bpp);
int screenDepth = ::GetDeviceCaps(hScreenDC, BITSPIXEL); int screenDepth = ::GetDeviceCaps(hScreenDC, BITSPIXEL);
HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, image.GetWidth(), image.GetHeight()); HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, image.GetWidth(), image.GetHeight());
HBITMAP hMaskBitmap = NULL;
HBITMAP hOldMaskBitmap = NULL;
HDC hMaskDC = NULL;
unsigned char maskR = 0;
unsigned char maskG = 0;
unsigned char maskB = 0;
// printf("Created bitmap %d\n", (int) hBitmap); // printf("Created bitmap %d\n", (int) hBitmap);
if (hBitmap == NULL) if (hBitmap == NULL)
{ {
@@ -399,9 +415,43 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
return FALSE; return FALSE;
} }
HDC hMemDC = ::CreateCompatibleDC(hScreenDC); HDC hMemDC = ::CreateCompatibleDC(hScreenDC);
::ReleaseDC(NULL, hScreenDC);
HBITMAP hOldBitmap = ::SelectObject(hMemDC, hBitmap); HBITMAP hOldBitmap = ::SelectObject(hMemDC, hBitmap);
::ReleaseDC(NULL, hScreenDC);
// created an mono-bitmap for the possible mask
bool hasMask = image.HasMask();
if ( hasMask )
{
#if USE_MASKS
// FIXME: we should be able to pass bpp = 1, but
// GdBlit can't handle a different depth
#if 0
hMaskBitmap = ::CreateBitmap( (WORD)image.GetWidth(), (WORD)image.GetHeight(), 1, 1, NULL );
#else
hMaskBitmap = ::CreateCompatibleBitmap( hMemDC, (WORD)image.GetWidth(), (WORD)image.GetHeight());
#endif
maskR = image.GetMaskRed();
maskG = image.GetMaskGreen();
maskB = image.GetMaskBlue();
if (!hMaskBitmap)
{
hasMask = FALSE;
}
else
{
hScreenDC = ::GetDC(NULL);
hMaskDC = ::CreateCompatibleDC(hScreenDC);
::ReleaseDC(NULL, hScreenDC);
hOldMaskBitmap = ::SelectObject( hMaskDC, hMaskBitmap);
}
#else
hasMask = FALSE;
#endif
}
int i, j; int i, j;
for (i = 0; i < image.GetWidth(); i++) for (i = 0; i < image.GetWidth(); i++)
@@ -413,11 +463,28 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
unsigned char blue = image.GetBlue(i, j); unsigned char blue = image.GetBlue(i, j);
::SetPixel(hMemDC, i, j, PALETTERGB(red, green, blue)); ::SetPixel(hMemDC, i, j, PALETTERGB(red, green, blue));
if (hasMask)
{
// scan the bitmap for the transparent colour and set the corresponding
// pixels in the mask to BLACK and the rest to WHITE
if (maskR == red && maskG == green && maskB == blue)
::SetPixel(hMaskDC, i, j, PALETTERGB(0, 0, 0));
else
::SetPixel(hMaskDC, i, j, PALETTERGB(255, 255, 255));
}
} }
} }
::SelectObject(hMemDC, hOldBitmap); ::SelectObject(hMemDC, hOldBitmap);
::DeleteDC(hMemDC); ::DeleteDC(hMemDC);
if (hasMask)
{
::SelectObject(hMaskDC, hOldMaskBitmap);
::DeleteDC(hMaskDC);
((wxBitmapRefData*)m_refData)->m_bitmapMask = new wxMask((WXHBITMAP) hMaskBitmap);
}
SetWidth(image.GetWidth()); SetWidth(image.GetWidth());
SetHeight(image.GetHeight()); SetHeight(image.GetHeight());

View File

@@ -886,7 +886,6 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
useMask = FALSE; useMask = FALSE;
} }
} }
if ( useMask ) if ( useMask )
{ {
#ifdef __WIN32__ #ifdef __WIN32__
@@ -902,8 +901,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
{ {
HDC cdc = GetHdc(); HDC cdc = GetHdc();
HDC hdcMem = ::CreateCompatibleDC(GetHdc()); HDC hdcMem = ::CreateCompatibleDC(GetHdc());
::SelectObject(hdcMem, GetHbitmapOf(bmp)); HBITMAP hOldBitmap = ::SelectObject(hdcMem, GetHbitmapOf(bmp));
#if wxUSE_PALETTE #if wxUSE_PALETTE
wxPalette *pal = bmp.GetPalette(); wxPalette *pal = bmp.GetPalette();
if ( pal && ::GetDeviceCaps(cdc,BITSPIXEL) <= 8 ) if ( pal && ::GetDeviceCaps(cdc,BITSPIXEL) <= 8 )
@@ -923,6 +921,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
::SelectPalette(hdcMem, oldPal, FALSE); ::SelectPalette(hdcMem, oldPal, FALSE);
#endif // wxUSE_PALETTE #endif // wxUSE_PALETTE
::SelectObject(hdcMem, hOldBitmap);
::DeleteDC(hdcMem); ::DeleteDC(hdcMem);
} }
@@ -967,7 +966,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
} }
#endif // wxUSE_PALETTE #endif // wxUSE_PALETTE
::SelectObject( memdc, hbitmap ); HBITMAP hOldBitmap = ::SelectObject( memdc, hbitmap );
::BitBlt( cdc, x, y, width, height, memdc, 0, 0, SRCCOPY); ::BitBlt( cdc, x, y, width, height, memdc, 0, 0, SRCCOPY);
#if wxUSE_PALETTE #if wxUSE_PALETTE
@@ -975,6 +974,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
::SelectPalette(memdc, oldPal, FALSE); ::SelectPalette(memdc, oldPal, FALSE);
#endif // wxUSE_PALETTE #endif // wxUSE_PALETTE
::SelectObject( memdc, hOldBitmap );
::DeleteDC( memdc ); ::DeleteDC( memdc );
::SetTextColor(GetHdc(), old_textground); ::SetTextColor(GetHdc(), old_textground);
@@ -1769,8 +1769,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
dc_buffer = ::CreateCompatibleDC(GetHdc()); dc_buffer = ::CreateCompatibleDC(GetHdc());
buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height); buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
#endif // wxUSE_DC_CACHEING/!wxUSE_DC_CACHEING #endif // wxUSE_DC_CACHEING/!wxUSE_DC_CACHEING
::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap()); HBITMAP hOldMaskBitmap = ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
::SelectObject(dc_buffer, buffer_bmap); HBITMAP hOldBufferBitmap = ::SelectObject(dc_buffer, buffer_bmap);
// copy dest to buffer // copy dest to buffer
if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height, if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
@@ -1816,8 +1816,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
} }
// tidy up temporary DCs and bitmap // tidy up temporary DCs and bitmap
::SelectObject(dc_mask, 0); ::SelectObject(dc_mask, hOldMaskBitmap);
::SelectObject(dc_buffer, 0); ::SelectObject(dc_buffer, hOldBufferBitmap);
#if !wxUSE_DC_CACHEING #if !wxUSE_DC_CACHEING
{ {

View File

@@ -283,3 +283,87 @@ int GetObject(HGDIOBJ hObj, int sz, LPVOID logObj)
return 0; return 0;
} }
} }
/* Not in wingdi.c in earlier versions of MicroWindows */
#if 0
HBITMAP WINAPI
CreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight)
{
MWBITMAPOBJ * hbitmap;
int size;
int linelen;
if(!hdc)
return NULL;
nWidth = MWMAX(nWidth, 1);
nHeight = MWMAX(nHeight, 1);
/* calc memory allocation size and linelen from width and height*/
if(!GdCalcMemGCAlloc(hdc->psd, nWidth, nHeight, 0, 0, &size, &linelen))
return NULL;
/* allocate gdi object*/
hbitmap = (MWBITMAPOBJ *)GdItemAlloc(sizeof(MWBITMAPOBJ)-1+size);
if(!hbitmap)
return NULL;
hbitmap->hdr.type = OBJ_BITMAP;
hbitmap->hdr.stockobj = FALSE;
hbitmap->width = nWidth;
hbitmap->height = nHeight;
/* create compatible with hdc*/
hbitmap->planes = hdc->psd->planes;
hbitmap->bpp = hdc->psd->bpp;
hbitmap->linelen = linelen;
hbitmap->size = size;
return (HBRUSH)hbitmap;
}
#endif
/* Attempt by JACS to create arbitrary bitmap
* TODO: make use of lpData
*/
HBITMAP WINAPI
CreateBitmap( int nWidth, int nHeight, int nPlanes, int bPP, LPCVOID lpData)
{
MWBITMAPOBJ * hbitmap;
int size;
int linelen;
HDC hScreenDC;
hScreenDC = GetDC(NULL);
nWidth = MWMAX(nWidth, 1);
nHeight = MWMAX(nHeight, 1);
/* calc memory allocation size and linelen from width and height*/
if(!GdCalcMemGCAlloc(hScreenDC->psd, nWidth, nHeight, nPlanes, bPP, &size, &linelen))
{
ReleaseDC(NULL, hScreenDC);
return NULL;
}
ReleaseDC(NULL, hScreenDC);
/* allocate gdi object*/
hbitmap = (MWBITMAPOBJ *)GdItemAlloc(sizeof(MWBITMAPOBJ)-1+size);
if(!hbitmap)
return NULL;
hbitmap->hdr.type = OBJ_BITMAP;
hbitmap->hdr.stockobj = FALSE;
hbitmap->width = nWidth;
hbitmap->height = nHeight;
/* create with specified parameters */
hbitmap->planes = nPlanes;
hbitmap->bpp = bPP;
hbitmap->linelen = linelen;
hbitmap->size = size;
/* TODO: copy data */
return (HBRUSH)hbitmap;
}

View File

@@ -1446,6 +1446,12 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
{ {
// TODO: is this consistent with other platforms?
// Still, negative width or height shouldn't be allowed
if (width < 0)
width = 0;
if (height < 0)
height = 0;
if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
{ {
wxLogLastError(wxT("MoveWindow")); wxLogLastError(wxT("MoveWindow"));

View File

@@ -154,10 +154,12 @@ void wxCheckBox::DoDraw(wxControlRenderer *renderer)
if ( m_status == Status_Checked ) if ( m_status == Status_Checked )
flags |= wxCONTROL_CHECKED; flags |= wxCONTROL_CHECKED;
wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
renderer->GetRenderer()-> renderer->GetRenderer()->
DrawCheckButton(dc, DrawCheckButton(dc,
GetLabel(), GetLabel(),
GetBitmap(GetState(flags), m_status), bitmap,
renderer->GetRect(), renderer->GetRect(),
flags, flags,
GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT

View File

@@ -466,6 +466,7 @@ void wxNotebook::DoDrawTab(wxDC& dc, const wxRect& rect, size_t n)
dc.SelectObject(bmp); dc.SelectObject(bmp);
dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID)); dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID));
m_imageList->Draw(image, dc, 0, 0, wxIMAGELIST_DRAW_NORMAL, TRUE); m_imageList->Draw(image, dc, 0, 0, wxIMAGELIST_DRAW_NORMAL, TRUE);
dc.SelectObject(wxNullBitmap);
#else #else
bmp = *m_imageList->GetBitmap(image); bmp = *m_imageList->GetBitmap(image);
#endif #endif

View File

@@ -2239,6 +2239,7 @@ void wxWin32Renderer::DrawCheckOrRadioButton(wxDC& dc,
rectLabel.SetRight(rect.GetRight()); rectLabel.SetRight(rect.GetRight());
} }
// THIS IS THE CULPRIT -- JACS
dc.DrawBitmap(bitmap, xBmp, yBmp, TRUE /* use mask */); dc.DrawBitmap(bitmap, xBmp, yBmp, TRUE /* use mask */);
DoDrawLabel( DoDrawLabel(
@@ -2291,10 +2292,12 @@ void wxWin32Renderer::DrawCheckButton(wxDC& dc,
else else
{ {
wxBitmap cbitmap(GetCheckBitmap(flags)); wxBitmap cbitmap(GetCheckBitmap(flags));
#if 1
DrawCheckOrRadioButton(dc, label, DrawCheckOrRadioButton(dc, label,
cbitmap, cbitmap,
rect, flags, align, indexAccel, rect, flags, align, indexAccel,
0); // no focus rect offset for checkboxes 0); // no focus rect offset for checkboxes
#endif
} }
} }