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.
// 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.
#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
// 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.
//
// 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.
//
# List of objects to compile
OBJS = minimal.o
-MTESTOBJS = mtest.o
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:
.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
wxImageList *imaglist)
: WidgetsPage(notebook)
{
- imaglist->Add(wxBitmap(combobox_xpm));
-
// init everything
m_chkSort =
m_chkReadonly = (wxCheckBox *)NULL;
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
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(),
delete m_lbox;
}
+#if wxUSE_CHECKLISTBOX
if ( m_chkCheck->GetValue() )
{
m_lbox = new wxCheckListBox(this, ListboxPage_Listbox,
flags);
}
else // just a listbox
+#endif
{
m_lbox = new wxListBox(this, ListboxPage_Listbox,
wxDefaultPosition, wxDefaultSize,
--- /dev/null
+##############################################################################
+# 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
bool wxBitmap::Create(int w, int h, int d)
{
-#ifndef __WXMICROWIN__
UnRef();
m_refData = new wxBitmapRefData;
GetBitmapData()->m_depth = d;
HBITMAP hbmp;
-
+#ifndef __WXMICROWIN__
if ( d > 0 )
{
hbmp = ::CreateBitmap(w, h, 1, d, NULL);
}
}
else
+#endif
{
ScreenHDC dc;
hbmp = ::CreateCompatibleBitmap(dc, w, h);
GetBitmapData()->m_ok = hbmp != 0;
#endif // WXWIN_COMPATIBILITY_2
return Ok();
-#else
- return FALSE;
-#endif
}
// ----------------------------------------------------------------------------
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") )
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") );
//
// 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