From e640f8231fbf0417f9ab5d378e7f218587cb6ac2 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 21 Dec 2001 17:01:02 +0000 Subject: [PATCH] MicroWindows tweaks git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13145 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/microwin/readme.txt | 37 ++++++++-- include/wx/msw/setup_microwin.h | 16 ++--- samples/minimal/makefile.mic | 10 --- samples/widgets/combobox.cpp | 31 +++++--- samples/widgets/listbox.cpp | 2 + samples/widgets/makefile.mic | 86 ++++++++++++++++++++++ src/msw/bitmap.cpp | 124 +++++++++++++++++++++++++++++--- src/msw/window.cpp | 2 +- 8 files changed, 262 insertions(+), 46 deletions(-) create mode 100644 samples/widgets/makefile.mic diff --git a/docs/microwin/readme.txt b/docs/microwin/readme.txt index 48df79ebf4..c2572f3d0a 100644 --- a/docs/microwin/readme.txt +++ b/docs/microwin/readme.txt @@ -106,17 +106,40 @@ wxMSW/wxMicroWindows port itself. Things missing from MicroWindows that need to be worked around ============================================================== +wxImage/inline XPM/::CreateBitmap support +----------------------------------------- + +This is the main obstacle to getting a good range +of widgets working, since wxUniversal uses inline XPMs +to implement most of the widgets. + +See src/engine/devimage.c for routines for loading JPEGs, +XPMs etc. Unfortunately the XPM routines are also #ifdefed +for FILE_IO, even though for inline XPMs we don't need file I/O. +(Embedded systems tend not to have file I/O, anyway.) + +Now, wxWindows has its own XPM decoder, src/common/xpmdecod.cpp, +so in theory we don't need to use MicroWindows' code there. +wxImage can load an inline XPM, _but_ we need to convert to +a wxBitmap since this is what the widgets need. + +There is no ::CreateBitmap or BITMAPINFO. (BMPs can be converted +to C using convbmp, then need to use Gr... functions.) + +So how can we convert from wxImage to wxBitmap in MicroWindows? + +Well, a simple-minded way would be to use CreateCompatibleBitmap +which returns an HBITMAP, select it into an HDC, and draw +the pixels from the wxImage to the HDC one by one with SetPixel. + + +Other missing features +---------------------- + No ::GetKeyState (see include/wx/msw/private.h). Should probably use GdOpenKeyboard/GdCloseKeyboard/GdReadKeyboard. Could perhaps emulate GetKeyState this way. -No ::CreateBitmap or BITMAPINFO. But BMPs can be converted -to C using convbmp, then need to use Gr... functions. -We MUST implement creation from XPMs, since wxUniversal -makes use of XPMs, or else create our own bitmaps for -drawing radioboxes, checkboxes etc.: see renderers -in src/univ. - No ::DestroyIcon, ::DestroyCursor - use ::DestroyObject instead? Also no LoadCursor, LoadImage. So how do we make cursors? No ::SetCursor. diff --git a/include/wx/msw/setup_microwin.h b/include/wx/msw/setup_microwin.h index 2950196005..472f8032f1 100644 --- a/include/wx/msw/setup_microwin.h +++ b/include/wx/msw/setup_microwin.h @@ -117,7 +117,7 @@ // Default is 1 // // Recommended setting: 1 but see comment in the beginning of this section -#define wxUSE_MEMORY_TRACING 1 +#define wxUSE_MEMORY_TRACING 0 // In debug mode, cause new and delete to be redefined globally. // If this causes problems (e.g. link errors), set this to 0. @@ -459,18 +459,18 @@ #define wxUSE_BMPBUTTON 1 // wxBitmapButton #define wxUSE_CALENDARCTRL 0 // wxCalendarCtrl #define wxUSE_CHECKBOX 1 // wxCheckBox -#define wxUSE_CHECKLISTBOX 0 // wxCheckListBox (requires wxUSE_OWNER_DRAWN) +#define wxUSE_CHECKLISTBOX 1 // wxCheckListBox (requires wxUSE_OWNER_DRAWN) #define wxUSE_CHOICE 1 // wxChoice #define wxUSE_COMBOBOX 1 // wxComboBox -#define wxUSE_GAUGE 0 // wxGauge +#define wxUSE_GAUGE 1 // wxGauge #define wxUSE_LISTBOX 1 // wxListBox #define wxUSE_LISTCTRL 0 // wxListCtrl -#define wxUSE_RADIOBOX 0 // wxRadioBox +#define wxUSE_RADIOBOX 1 // wxRadioBox #define wxUSE_RADIOBTN 1 // wxRadioButton #define wxUSE_SCROLLBAR 1 // wxScrollBar #define wxUSE_SLIDER 1 // wxSlider -#define wxUSE_SPINBTN 0 // wxSpinButton -#define wxUSE_SPINCTRL 0 // wxSpinCtrl +#define wxUSE_SPINBTN 1 // wxSpinButton +#define wxUSE_SPINCTRL 1 // wxSpinCtrl #define wxUSE_STATBOX 1 // wxStaticBox #define wxUSE_STATLINE 1 // wxStaticLine #define wxUSE_STATTEXT 1 // wxStaticText @@ -521,7 +521,7 @@ // Default is 1. // // Recommended setting: 1 -#define wxUSE_NOTEBOOK 0 +#define wxUSE_NOTEBOOK 1 // wxTabDialog is a generic version of wxNotebook but it is incompatible with // the new class. It shouldn't be used in new code. @@ -574,7 +574,7 @@ // // Recommended setting: 1 (set it to 0 if you don't use any of the controls // enumerated above, then this class is mostly useless too) -#define wxUSE_IMAGLIST 0 +#define wxUSE_IMAGLIST 1 // Use wxMenu, wxMenuBar, wxMenuItem. // diff --git a/samples/minimal/makefile.mic b/samples/minimal/makefile.mic index 49715461ef..6cabbbfdcc 100644 --- a/samples/minimal/makefile.mic +++ b/samples/minimal/makefile.mic @@ -51,7 +51,6 @@ include $(TOP)/Makefile.rules # List of objects to compile OBJS = minimal.o -MTESTOBJS = mtest.o all: minimal @@ -64,9 +63,6 @@ all: minimal minimal: $(OBJS) $(MWINLIBS) $(WXLIB) $(TOP)/config $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ $(WXLIB) $(MWINLIBS) -lm -mtest: $(MTESTOBJS) $(MWINLIBS) $(TOP)/config - $(CC) $(CFLAGS) $(LDFLAGS) $(MTESTOBJS) -o $@ $(MWINLIBS) - #.SUFFIXES: .cpp .cxx .c #.c.o: @@ -78,12 +74,6 @@ mtest: $(MTESTOBJS) $(MWINLIBS) $(TOP)/config .cpp.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $*.cpp -#$(COMMDIR)/appcmn.o: $(COMMDIR)/appcmn.cpp -# $(CC) -c $(CPPFLAGS) -o $@ $*.cpp - -#appcmn.o: $(COMMDIR)/appcmn.cpp -# $(CC) $(CPPFLAGS) -c -o $@ $< - cleanwx: -$(RM) *.o -$(RM) minimal diff --git a/samples/widgets/combobox.cpp b/samples/widgets/combobox.cpp index b270e2656c..b4a4ecc961 100644 --- a/samples/widgets/combobox.cpp +++ b/samples/widgets/combobox.cpp @@ -182,8 +182,6 @@ ComboboxWidgetsPage::ComboboxWidgetsPage(wxNotebook *notebook, wxImageList *imaglist) : WidgetsPage(notebook) { - imaglist->Add(wxBitmap(combobox_xpm)); - // init everything m_chkSort = m_chkReadonly = (wxCheckBox *)NULL; @@ -191,6 +189,8 @@ ComboboxWidgetsPage::ComboboxWidgetsPage(wxNotebook *notebook, m_combobox = (wxComboBox *)NULL; m_sizerCombo = (wxSizer *)NULL; + imaglist->Add(wxBitmap(combobox_xpm)); + /* What we create here is a frame having 3 panes: style pane is the leftmost one, in the middle the pane with buttons allowing to perform @@ -441,38 +441,49 @@ void ComboboxWidgetsPage::OnButtonAddSeveral(wxCommandEvent& event) void ComboboxWidgetsPage::OnUpdateUICurText(wxUpdateUIEvent& event) { - event.SetText( wxString::Format(_T("%d"), m_combobox->GetSelection()) ); + if (m_combobox) + event.SetText( wxString::Format(_T("%d"), m_combobox->GetSelection()) ); } void ComboboxWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event) { - event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() ); + if (m_combobox) + event.Enable( m_chkSort->GetValue() || m_chkReadonly->GetValue() ); } void ComboboxWidgetsPage::OnUpdateUIDeleteButton(wxUpdateUIEvent& event) { - unsigned long n; - event.Enable(m_textDelete->GetValue().ToULong(&n) && - (n < (unsigned)m_combobox->GetCount())); + if (m_combobox) + { + unsigned long n; + event.Enable(m_textDelete->GetValue().ToULong(&n) && + (n < (unsigned)m_combobox->GetCount())); + } } void ComboboxWidgetsPage::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event) { - event.Enable(m_combobox->GetSelection() != -1); + if (m_combobox) + event.Enable(m_combobox->GetSelection() != -1); } void ComboboxWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event) { - event.Enable(m_combobox->GetCount() != 0); + if (m_combobox) + event.Enable(m_combobox->GetCount() != 0); } void ComboboxWidgetsPage::OnUpdateUIAddSeveral(wxUpdateUIEvent& event) { - event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT)); + if (m_combobox) + event.Enable(!(m_combobox->GetWindowStyle() & wxCB_SORT)); } void ComboboxWidgetsPage::OnComboText(wxCommandEvent& event) { + if (!m_combobox) + return; + wxString s = event.GetString(); wxASSERT_MSG( s == m_combobox->GetValue(), diff --git a/samples/widgets/listbox.cpp b/samples/widgets/listbox.cpp index 7541db358b..43cb38118d 100644 --- a/samples/widgets/listbox.cpp +++ b/samples/widgets/listbox.cpp @@ -355,6 +355,7 @@ void ListboxWidgetsPage::CreateLbox() delete m_lbox; } +#if wxUSE_CHECKLISTBOX if ( m_chkCheck->GetValue() ) { m_lbox = new wxCheckListBox(this, ListboxPage_Listbox, @@ -363,6 +364,7 @@ void ListboxWidgetsPage::CreateLbox() flags); } else // just a listbox +#endif { m_lbox = new wxListBox(this, ListboxPage_Listbox, wxDefaultPosition, wxDefaultSize, diff --git a/samples/widgets/makefile.mic b/samples/widgets/makefile.mic new file mode 100644 index 0000000000..2efc49c71a --- /dev/null +++ b/samples/widgets/makefile.mic @@ -0,0 +1,86 @@ +############################################################################## +# Microwindows template Makefile +# Copyright (c) 2000 Martin Jolicoeur, Greg Haerr +############################################################################## + +TOP=$(MICROWINDOWS) +ifeq "$(MICROWINDOWS)" "" +TOP=/home/julians/local/microwindows/microwindows-0.89pre8/src +endif + +CONFIG = $(TOP)/config +WXDIR = ../.. +OBJSUFF = o +SRCSUFF = cpp +WXLIB=$(WXDIR)/lib/libwx.a +AROPTIONS = ruv +RANLIB = ranlib +RM = rm -f + +ZLIBLIB = $(WXDIR)/lib/libzlib.a +PNGLIB = $(WXDIR)/lib/libpng.a +JPEGLIB = $(WXDIR)/lib/libjpeg.a +TIFFLIB = $(WXDIR)/lib/libtiff.a + +include $(CONFIG) + +######################## Additional Flags section ############################ + +# Directories list for header files +INCLUDEDIRS += -I$(WXDIR)/include +# Defines for preprocessor +DEFINES += -DMWIN -D__WXMSW__ -D__WXMICROWIN__ -D__WXUNIVERSAL__ -D__WIN32__ -D__WIN95__ -DHAVE_BOOL -DMICROWIN_TODO=1 -D__UNIX__ -DHAVE_NANOSLEEP -DMICROWIN_NOCONTROLS -D__WXDEBUG__ -DwxSIZE_T_IS_UINT -DWXWIN_OS_DESCRIPTION="\"MicroWindows\"" + +# Compilation flags for C files OTHER than include directories +CFLAGS += +# Preprocessor flags OTHER than defines +CPPFLAGS += +# Linking flags +#LDFLAGS += -lwx -L$(WXDIR)/lib +LDFLAGS += $(WXLIB) + +############################# targets section ################################ + +# If you want to create a library with the objects files, define the name here +LIBNAME = + +# If we put it below OBJS=, Makefile.rules includes .depend +# and it continually looks for .c files to satisfy .o.cpp +# dependency. What's going on there? +include $(TOP)/Makefile.rules + +# List of objects to compile +OBJS = button.o combobox.o gauge.o listbox.o notebook.o radiobox.o slider.o spinbtn.o \ + static.o textctrl.o widgets.o + +all: widgets + +######################### Makefile.rules section ############################# + + + +######################## Tools targets section ############################### + +widgets: $(OBJS) $(MWINLIBS) $(WXLIB) $(TOP)/config + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ $(WXLIB) $(MWINLIBS) -lm + +#.SUFFIXES: .cpp .cxx .c + +#.c.o: +# $(CC) -c $(CFLAGS) $(CFLAGS) -o $@ $*.c + +.cxx.o: + $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $*.cxx + +.cpp.o: + $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $*.cpp + +cleanwx: + -$(RM) *.o + -$(RM) widgets + +wx: + @pushd $(WXDIR)/src/msw; make -f makefile.mic all; popd + +wxfull: + @pushd $(WXDIR)/src/msw; make -f makefile.mic cleanwx all; popd diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 9f62b5e7c0..0118ff56bd 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -332,7 +332,6 @@ wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type) bool wxBitmap::Create(int w, int h, int d) { -#ifndef __WXMICROWIN__ UnRef(); m_refData = new wxBitmapRefData; @@ -342,7 +341,7 @@ bool wxBitmap::Create(int w, int h, int d) GetBitmapData()->m_depth = d; HBITMAP hbmp; - +#ifndef __WXMICROWIN__ if ( d > 0 ) { hbmp = ::CreateBitmap(w, h, 1, d, NULL); @@ -352,6 +351,7 @@ bool wxBitmap::Create(int w, int h, int d) } } else +#endif { ScreenHDC dc; hbmp = ::CreateCompatibleBitmap(dc, w, h); @@ -369,9 +369,6 @@ bool wxBitmap::Create(int w, int h, int d) GetBitmapData()->m_ok = hbmp != 0; #endif // WXWIN_COMPATIBILITY_2 return Ok(); -#else - return FALSE; -#endif } // ---------------------------------------------------------------------------- @@ -383,8 +380,56 @@ bool wxBitmap::Create(int w, int h, int d) bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) { #ifdef __WXMICROWIN__ - // TODO - return FALSE; + + // Initial attempt at a simple-minded implementation. + // The bitmap will always be created at the screen depth, + // so the 'depth' argument is ignored. + // TODO: transparency (create a mask image) + + HDC hScreenDC = ::GetDC(NULL); + int screenDepth = ::GetDeviceCaps(hScreenDC, BITSPIXEL); + + HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, image.GetWidth(), image.GetHeight()); + if (hBitmap == NULL) + { + ::ReleaseDC(NULL, hScreenDC); + return FALSE; + } + HDC hMemDC = ::CreateCompatibleDC(hScreenDC); + ::ReleaseDC(NULL, hScreenDC); + + HBITMAP hOldBitmap = ::SelectObject(hMemDC, hBitmap); + + int i, j; + for (i = 0; i < image.GetWidth(); i++) + { + for (j = 0; j < image.GetHeight(); j++) + { + unsigned char red = image.GetRed(i, j); + unsigned char green = image.GetGreen(i, j); + unsigned char blue = image.GetBlue(i, j); + + ::SetPixel(hMemDC, i, j, PALETTERGB(red, green, blue)); + } + } + + ::SelectObject(hMemDC, hOldBitmap); + ::DeleteDC(hMemDC); + + m_refData = new wxBitmapRefData(); + + SetWidth(image.GetWidth()); + SetHeight(image.GetHeight()); + SetDepth(screenDepth); + SetHBITMAP( (WXHBITMAP) hBitmap ); + +#if wxUSE_PALETTE + // Copy the palette from the source image + SetPalette(image.GetPalette()); +#endif // wxUSE_PALETTE + + return TRUE; + #else wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") ) @@ -621,9 +666,68 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) wxImage wxBitmap::ConvertToImage() const { #ifdef __WXMICROWIN__ - // TODO - return wxImage(); -#else + // Initial attempt at a simple-minded implementation. + // The bitmap will always be created at the screen depth, + // so the 'depth' argument is ignored. + // TODO: transparency (create a mask image) + + if (!Ok()) + { + wxFAIL_MSG( wxT("bitmap is invalid") ); + return wxNullImage; + } + + wxImage image; + + wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") ); + + // create an wxImage object + int width = GetWidth(); + int height = GetHeight(); + image.Create( width, height ); + unsigned char *data = image.GetData(); + if( !data ) + { + wxFAIL_MSG( wxT("could not allocate data for image") ); + return wxNullImage; + } + + HDC hScreenDC = ::GetDC(NULL); + + HDC hMemDC = ::CreateCompatibleDC(hScreenDC); + ::ReleaseDC(NULL, hScreenDC); + + HBITMAP hBitmap = (HBITMAP) GetHBITMAP(); + + HBITMAP hOldBitmap = ::SelectObject(hMemDC, hBitmap); + + int i, j; + for (i = 0; i < GetWidth(); i++) + { + for (j = 0; j < GetHeight(); j++) + { + COLORREF color = ::GetPixel(hMemDC, i, j); + unsigned char red = GetRValue(color); + unsigned char green = GetGValue(color); + unsigned char blue = GetBValue(color); + + image.SetRGB(i, j, red, green, blue); + } + } + + ::SelectObject(hMemDC, hOldBitmap); + ::DeleteDC(hMemDC); + +#if wxUSE_PALETTE + // Copy the palette from the source image + if (GetPalette()) + image.SetPalette(* GetPalette()); +#endif // wxUSE_PALETTE + + return image; + +#else // __MICROWIN__ + wxImage image; wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") ); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 4cfa88b3c9..a2dca1ea29 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -377,7 +377,7 @@ bool wxWindowMSW::Create(wxWindow *parent, // // the correct solution is to create the controls as siblings of the // static box - wxASSERT_MSG( !wxDynamicCastThis(wxStaticBox), + wxASSERT_MSG( !wxDynamicCast(parent, wxStaticBox), _T("wxStaticBox can't be used as a window parent!") ); #endif // wxUSE_STATBOX -- 2.47.2