From: David Webster Date: Mon, 20 Sep 1999 04:49:19 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/45fcbf3b7a7c9cfd96e67278e4eaa12e8e015651 *** empty log message *** git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3726 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/defs.h b/include/wx/defs.h index e35d3e8c97..da04f7bc48 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -465,7 +465,8 @@ enum wxMGL_UNIX, // MGL with direct hardware access wxMGL_X, // MGL on X wxMGL_WIN32, // MGL on Win32 - wxMGL_OS2 // MGL on OS/2 + wxMGL_OS2, // MGL on OS/2 + wxWINDOWS_OS2 // Native OS/2 PM }; // ---------------------------------------------------------------------------- @@ -1469,8 +1470,13 @@ typedef unsigned long WXHDC; typedef unsigned int WXUINT; typedef unsigned long WXDWORD; typedef unsigned short WXWORD; +#ifdef __WXMSW__ typedef unsigned int WXWPARAM; typedef long WXLPARAM; +#else +# define WXWPARAM MPARAM +# define WXLPARAM MPARAM +#endif typedef unsigned long WXCOLORREF; typedef void * WXRGNDATA; typedef void * WXMSG; diff --git a/include/wx/os2/control.h b/include/wx/os2/control.h index d2aac6bbc7..d3e7b4020e 100644 --- a/include/wx/os2/control.h +++ b/include/wx/os2/control.h @@ -1,50 +1,94 @@ ///////////////////////////////////////////////////////////////////////////// // Name: control.h // Purpose: wxControl class -// Author: AUTHOR +// Author: David Webster // Modified by: -// Created: ??/??/98 +// Created: 09/17/99 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_CONTROL_H_ #define _WX_CONTROL_H_ #ifdef __GNUG__ -#pragma interface "control.h" + #pragma interface "control.h" #endif -#include "wx/window.h" -#include "wx/list.h" -#include "wx/validate.h" - // General item class -class WXDLLEXPORT wxControl: public wxControlBase +class WXDLLEXPORT wxControl : public wxControlBase { - DECLARE_ABSTRACT_CLASS(wxControl) + DECLARE_ABSTRACT_CLASS(wxControl) + public: wxControl(); - ~wxControl(); + virtual ~wxControl(); + + // Simulates an event + virtual void Command(wxCommandEvent& event) { ProcessCommand(event); } + + // implementation from now on + // -------------------------- + + // Calls the callback and appropriate event handlers + bool ProcessCommand(wxCommandEvent& event); + + // OS2-specific + virtual bool OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); + + // For ownerdraw items + virtual bool OS2OnDraw(WXDRAWITEMSTRUCT *WXUNUSED(item)) { return FALSE; }; + virtual bool OS2OnMeasure(WXMEASUREITEMSTRUCT *WXUNUSED(item)) { return FALSE; }; + + wxList& GetSubcontrols() { return m_subControls; } + + void OnEraseBackground(wxEraseEvent& event); - virtual void Command(wxCommandEvent& WXUNUSED(event)) {}; // Simulates an event - virtual void ProcessCommand(wxCommandEvent& event); // Calls the callback and - // appropriate event handlers - virtual void SetLabel(const wxString& label); - virtual wxString GetLabel() const ; +#if WXWIN_COMPATIBILITY + virtual void SetButtonColour(const wxColour& WXUNUSED(col)) { } + wxColour* GetButtonColour() const { return NULL; } - // Places item in centre of panel - so can't be used BEFORE panel->Fit() - void Centre(int direction = wxHORIZONTAL); - inline void Callback(const wxFunction function) { m_callback = function; }; // Adds callback + inline virtual void SetLabelFont(const wxFont& font); + inline virtual void SetButtonFont(const wxFont& font); + inline wxFont& GetLabelFont() const; + inline wxFont& GetButtonFont() const; - inline wxFunction GetCallback() { return m_callback; } + // Adds callback + inline void Callback(const wxFunction function); + + wxFunction GetCallback() { return m_callback; } protected: wxFunction m_callback; // Callback associated with the window +#endif // WXWIN_COMPATIBILITY + +protected: + // For controls like radiobuttons which are really composite + wxList m_subControls; + + virtual wxSize DoGetBestSize(); -DECLARE_EVENT_TABLE() + // create the control of the given class with the given style, returns FALSE + // if creation failed + bool OS2CreateControl(const wxChar *classname, WXDWORD style); + + // determine the extended styles combination for this window (may slightly + // modify styl parameter) + WXDWORD GetExStyle(WXDWORD& style) const; + +private: + DECLARE_EVENT_TABLE() }; + +#if WXWIN_COMPATIBILITY + inline void wxControl::Callback(const wxFunction f) { m_callback = f; }; + inline wxFont& wxControl::GetLabelFont() const { return GetFont(); } + inline wxFont& wxControl::GetButtonFont() const { return GetFont(); } + inline void wxControl::SetLabelFont(const wxFont& font) { SetFont(font); } + inline void wxControl::SetButtonFont(const wxFont& font) { SetFont(font); } +#endif // WXWIN_COMPATIBILITY + #endif // _WX_CONTROL_H_ diff --git a/include/wx/os2/private.h b/include/wx/os2/private.h index 922c172436..655a4d21a2 100644 --- a/include/wx/os2/private.h +++ b/include/wx/os2/private.h @@ -1,21 +1,206 @@ ///////////////////////////////////////////////////////////////////////////// // Name: private.h -// Purpose: Private declarations -// Author: AUTHOR +// Purpose: Private declarations: as this header is only included by +// wxWindows itself, it may contain identifiers which don't start +// with "wx". +// Author: Julian Smart // Modified by: -// Created: ??/??/98 +// Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_PRIVATE_H_ #define _WX_PRIVATE_H_ -#include "wx/defs.h" +#define INCL_DOS +#define INCL_PM +#include -/* TODO: put any private declarations here. +class WXDLLEXPORT wxFont; +class WXDLLEXPORT wxWindow; + +// --------------------------------------------------------------------------- +// private constants +// --------------------------------------------------------------------------- + +// Conversion +static const double METRIC_CONVERSION_CONSTANT = 0.0393700787; + +// Scaling factors for various unit conversions +static const double mm2inches = (METRIC_CONVERSION_CONSTANT); +static const double inches2mm = (1/METRIC_CONVERSION_CONSTANT); + +static const double mm2twips = (METRIC_CONVERSION_CONSTANT*1440); +static const double twips2mm = (1/(METRIC_CONVERSION_CONSTANT*1440)); + +static const double mm2pt = (METRIC_CONVERSION_CONSTANT*72); +static const double pt2mm = (1/(METRIC_CONVERSION_CONSTANT*72)); + +// --------------------------------------------------------------------------- +// standard icons from the resources +// --------------------------------------------------------------------------- + +WXDLLEXPORT_DATA(extern HICON) wxSTD_FRAME_ICON; +WXDLLEXPORT_DATA(extern HICON) wxSTD_MDIPARENTFRAME_ICON; +WXDLLEXPORT_DATA(extern HICON) wxSTD_MDICHILDFRAME_ICON; +WXDLLEXPORT_DATA(extern HICON) wxDEFAULT_FRAME_ICON; +WXDLLEXPORT_DATA(extern HICON) wxDEFAULT_MDIPARENTFRAME_ICON; +WXDLLEXPORT_DATA(extern HICON) wxDEFAULT_MDICHILDFRAME_ICON; +WXDLLEXPORT_DATA(extern HFONT) wxSTATUS_LINE_FONT; + +// --------------------------------------------------------------------------- +// this defines a CASTWNDPROC macro which casts a pointer to the type of a +// window proc for PM. +// MPARAM is a void * but is really a 32-bit value +// --------------------------------------------------------------------------- + +typedef MRESULT (APIENTRY * WndProcCast) (HWND, ULONG, MPARAM, MPARAM); +#define CASTWNDPROC (WndProcCast) + +#if wxUSE_ITSY_BITSY + #define IBS_HORZCAPTION 0x4000L + #define IBS_VERTCAPTION 0x8000L + + UINT WINAPI ibGetCaptionSize( HWND hWnd ) ; + UINT WINAPI ibSetCaptionSize( HWND hWnd, UINT nSize ) ; + LRESULT WINAPI ibDefWindowProc( HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam ) ; + VOID WINAPI ibAdjustWindowRect( HWND hWnd, LPRECT lprc ) ; +#endif // wxUSE_ITSY_BITSY + +/* + * Decide what window classes we're going to use + * for this combination of CTl3D/FAFA settings */ +#define STATIC_CLASS _T("STATIC") +#define STATIC_FLAGS (SS_TEXT|DT_LEFT|SS_LEFT|WS_VISIBLE) +#define CHECK_CLASS "BUTTON" +#define CHECK_FLAGS (BS_AUTOCHECKBOX|WS_TABSTOP) +#define CHECK_IS_FAFA FALSE +#define RADIO_CLASS "BUTTON" +#define RADIO_FLAGS (BS_AUTORADIOBUTTON|WS_VISIBLE) +#define RADIO_SIZE 20 +#define RADIO_IS_FAFA FALSE +#define PURE_WINDOWS +/* PM has no group box button style +#define GROUP_CLASS "BUTTON" +#define GROUP_FLAGS (BS_GROUPBOX|WS_CHILD|WS_VISIBLE) +*/ + +/* +#define BITCHECK_FLAGS (FB_BITMAP|FC_BUTTONDRAW|FC_DEFAULT|WS_VISIBLE) +#define BITRADIO_FLAGS (FC_BUTTONDRAW|FB_BITMAP|FC_RADIO|WS_CHILD|WS_VISIBLE) +*/ + +// --------------------------------------------------------------------------- +// misc macros +// --------------------------------------------------------------------------- + +#define MEANING_CHARACTER '0' +#define DEFAULT_ITEM_WIDTH 200 +#define DEFAULT_ITEM_HEIGHT 80 + +// Scale font to get edit control height +#define EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy) (3*(cy)/2) + +// Generic subclass proc, for panel item moving/sizing and intercept +// EDIT control VK_RETURN messages +extern LONG APIENTRY _EXPORT + wxSubclassedGenericControlProc(WXHWND hWnd, WXDWORD message, WXWPARAM wParam, WXLPARAM lParam); + +// --------------------------------------------------------------------------- +// constants which might miss from some compilers' headers +// --------------------------------------------------------------------------- + +#if !defined(WS_EX_CLIENTEDGE) + #define WS_EX_CLIENTEDGE 0 +#endif + +#ifndef ENDSESSION_LOGOFF + #define ENDSESSION_LOGOFF 0x80000000 +#endif + +// --------------------------------------------------------------------------- +// debug messages -- OS/2 has no native debug output system +// --------------------------------------------------------------------------- + +// --------------------------------------------------------------------------- +// macros to make casting between WXFOO and FOO a bit easier: the GetFoo() +// returns Foo cast to the Windows type for oruselves, while GetFooOf() takes +// an argument which should be a pointer or reference to the object of the +// corresponding class (this depends on the macro) +// --------------------------------------------------------------------------- + +#define GetHwnd() ((HWND)GetHWND()) +#define GetHwndOf(win) ((HWND)((win)->GetHWND())) +// old name +#define GetWinHwnd GetHwndOf + +#define GetHdc() ((HDC)GetHDC()) +#define GetHdcOf(dc) ((HDC)(dc).GetHDC()) + +#define GetHicon() ((HICON)GetHICON()) +#define GetHiconOf(icon) ((HICON)(icon).GetHICON()) + +#define GetHaccel() ((HACCEL)GetHACCEL()) +#define GetHaccelOf(table) ((HACCEL)((table).GetHACCEL())) + +#define GetHmenu() ((HMENU)GetHMenu()) +#define GetHmenuOf(menu) ((HMENU)menu->GetHMenu()) + +// --------------------------------------------------------------------------- +// global data +// --------------------------------------------------------------------------- + +// The MakeProcInstance version of the function wxSubclassedGenericControlProc +WXDLLEXPORT_DATA(extern FARPROC) wxGenericControlSubClassProc; +WXDLLEXPORT_DATA(extern wxChar*) wxBuffer; +WXDLLEXPORT_DATA(extern HINSTANCE) wxhInstance; + +// --------------------------------------------------------------------------- +// global functions +// --------------------------------------------------------------------------- + +extern "C" +{ +WXDLLEXPORT HINSTANCE wxGetInstance(); +} + +WXDLLEXPORT void wxSetInstance(HINSTANCE hInst); + +WXDLLEXPORT wxWindow* wxFindWinFromHandle(WXHWND hWnd); + +WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font); +WXDLLEXPORT void wxFillLogFont(LOGFONT *logFont, wxFont *font); +WXDLLEXPORT wxFont wxCreateFontFromLogFont(LOGFONT *logFont); + +WXDLLEXPORT void wxSliderEvent(WXHWND control, WXWORD wParam, WXWORD pos); +WXDLLEXPORT void wxScrollBarEvent(WXHWND hbar, WXWORD wParam, WXWORD pos); + +// Find maximum size of window/rectangle +WXDLLEXPORT extern void wxFindMaxSize(WXHWND hwnd, RECT *rect); + +WXDLLEXPORT wxWindow* wxFindControlFromHandle(WXHWND hWnd); +WXDLLEXPORT void wxAddControlHandle(WXHWND hWnd, wxWindow *item); + +// Safely get the window text (i.e. without using fixed size buffer) +WXDLLEXPORT extern wxString wxGetWindowText(WXHWND hWnd); + +// get the window class name +WXDLLEXPORT extern wxString wxGetWindowClass(WXHWND hWnd); + +// get the window id (should be unsigned, hence this is not wxWindowID which +// is, for mainly historical reasons, signed) +WXDLLEXPORT extern WXWORD wxGetWindowId(WXHWND hWnd); + +// Does this window style specify any border? +inline bool wxStyleHasBorder(long style) +{ + return (style & (wxSIMPLE_BORDER | wxRAISED_BORDER | + wxSUNKEN_BORDER | wxDOUBLE_BORDER)) != 0; +} + #endif // _WX_PRIVATE_H_ diff --git a/src/makeva.env b/src/makeva.env index f82e994c3a..af5011b340 100644 --- a/src/makeva.env +++ b/src/makeva.env @@ -17,7 +17,7 @@ OS2LIBFLAGS=/NOL /NOE OS2LIBS=CPPOM30.lib CPPOOC3.LIB OS2386.LIB # Change this to your WXWIN directory -WXDIR=h:\dev\Wx2\wxwindows +WXDIR=j:\dev\Wx2\wxwindows WXSRC=$(WXDIR)\src\os2 WXINC=$(WXDIR)\include diff --git a/src/os2/control.cpp b/src/os2/control.cpp index b141a80ff1..9d80a1c83b 100644 --- a/src/os2/control.cpp +++ b/src/os2/control.cpp @@ -1,95 +1,221 @@ ///////////////////////////////////////////////////////////////////////////// // Name: control.cpp // Purpose: wxControl class -// Author: AUTHOR +// Author: David Webster // Modified by: -// Created: ??/??/98 +// Created: 09/17/99 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation "control.h" #endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/event.h" +#include "wx/app.h" +#include "wx/dcclient.h" +#endif + #include "wx/control.h" #if !USE_SHARED_LIBRARY IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow) BEGIN_EVENT_TABLE(wxControl, wxWindow) + EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground) END_EVENT_TABLE() #endif // Item members wxControl::wxControl() { - m_backgroundColour = *wxWHITE; - m_foregroundColour = *wxBLACK; - m_callback = 0; + m_backgroundColour = *wxWHITE; + m_foregroundColour = *wxBLACK; + +#if WXWIN_COMPATIBILITY + m_callback = 0; +#endif // WXWIN_COMPATIBILITY } wxControl::~wxControl() { - // If we delete an item, we should initialize the parent panel, - // because it could now be invalid. - wxWindow *parent = (wxWindow *)GetParent(); - if (parent) - { - if (parent->GetDefaultItem() == (wxButton*) this) - parent->SetDefaultItem(NULL); - } + m_isBeingDeleted = TRUE; } -void wxControl::SetLabel(const wxString& label) +bool wxControl::OS2CreateControl(const wxChar *classname, WXDWORD style) { - // TODO + m_hWnd = (WXHWND)::CreateWindowEx + ( + GetExStyle(style), // extended style + classname, // the kind of control to create + NULL, // the window name + style, // the window style + 0, 0, 0, 0, // the window position and size + GetHwndOf(GetParent()), // parent + (HMENU)GetId(), // child id + wxGetInstance(), // app instance + NULL // creation parameters + ); + + if ( !m_hWnd ) + { +#ifdef __WXDEBUG__ + wxLogError(_T("Failed to create a control of class '%s'"), classname); +#endif // DEBUG + + return FALSE; + } + + // subclass again for purposes of dialog editing mode + SubclassWin(m_hWnd); + + // controls use the same font and colours as their parent dialog by default + InheritAttributes(); + + return TRUE; } -wxString wxControl::GetLabel() const +wxSize wxControl::DoGetBestSize() { - // TODO - return wxString(""); + return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT); } -void wxControl::ProcessCommand (wxCommandEvent & event) +bool wxControl::ProcessCommand(wxCommandEvent& event) { - // Tries: - // 1) A callback function (to become obsolete) - // 2) OnCommand, starting at this window and working up parent hierarchy - // 3) OnCommand then calls ProcessEvent to search the event tables. - if (m_callback) +#if WXWIN_COMPATIBILITY + if ( m_callback ) { - (void) (*(m_callback)) (*this, event); + (void)(*m_callback)(this, event); + + return TRUE; } else +#endif // WXWIN_COMPATIBILITY + + return GetEventHandler()->ProcessEvent(event); +} + +bool wxControl::OS2OnNotify(int idCtrl, + WXLPARAM lParam, + WXLPARAM* result) +{ + wxCommandEvent event(wxEVT_NULL, m_windowId); + wxEventType eventType = wxEVT_NULL; + NMHDR *hdr1 = (NMHDR*) lParam; + switch ( hdr1->code ) { - GetEventHandler()->OnCommand(*this, event); + case NM_CLICK: + eventType = wxEVT_COMMAND_LEFT_CLICK; + break; + + case NM_DBLCLK: + eventType = wxEVT_COMMAND_LEFT_DCLICK; + break; + + case NM_RCLICK: + eventType = wxEVT_COMMAND_RIGHT_CLICK; + break; + + case NM_RDBLCLK: + eventType = wxEVT_COMMAND_RIGHT_DCLICK; + break; + + case NM_SETFOCUS: + eventType = wxEVT_COMMAND_SET_FOCUS; + break; + + case NM_KILLFOCUS: + eventType = wxEVT_COMMAND_KILL_FOCUS; + break; + + case NM_RETURN: + eventType = wxEVT_COMMAND_ENTER; + break; + + default: + return wxWindow::OS2OnNotify(idCtrl, lParam, result); } + + event.SetEventType(eventType); + event.SetEventObject(this); + + return GetEventHandler()->ProcessEvent(event); } -void wxControl::Centre (int direction) +void wxControl::OnEraseBackground(wxEraseEvent& event) +{ + // In general, you don't want to erase the background of a control, + // or you'll get a flicker. + // TODO: move this 'null' function into each control that + // might flicker. + + RECT rect; +/* +* below is msw code. +* TODO: convert to PM Code +* ::GetClientRect((HWND) GetHWND(), &rect); +* +* HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), +* GetBackgroundColour().Green(), +* GetBackgroundColour().Blue())); +* int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT); +* +* ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush); +* ::DeleteObject(hBrush); +* ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode); +*/ +} + +WXDWORD wxControl::GetExStyle(WXDWORD& style) const +{ + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ; + + // Even with extended styles, need to combine with WS_BORDER + // for them to look right. + if ( want3D || wxStyleHasBorder(m_windowStyle) ) + style |= WS_BORDER; + + return exStyle; +} + +// --------------------------------------------------------------------------- +// global functions +// --------------------------------------------------------------------------- + +// Call this repeatedly for several wnds to find the overall size +// of the widget. +// Call it initially with -1 for all values in rect. +// Keep calling for other widgets, and rect will be modified +// to calculate largest bounding rectangle. +void wxFindMaxSize(WXHWND wnd, RECT *rect) { - int x, y, width, height, panel_width, panel_height, new_x, new_y; + int left = rect->left; + int right = rect->right; + int top = rect->top; + int bottom = rect->bottom; - wxWindow *parent = (wxWindow *) GetParent (); - if (!parent) - return; + GetWindowRect((HWND) wnd, rect); - parent->GetClientSize (&panel_width, &panel_height); - GetSize (&width, &height); - GetPosition (&x, &y); + if (left < 0) + return; - new_x = x; - new_y = y; + if (left < rect->left) + rect->left = left; - if (direction & wxHORIZONTAL) - new_x = (int) ((panel_width - width) / 2); + if (right > rect->right) + rect->right = right; - if (direction & wxVERTICAL) - new_y = (int) ((panel_height - height) / 2); + if (top < rect->top) + rect->top = top; - SetSize (new_x, new_y, width, height); + if (bottom > rect->bottom) + rect->bottom = bottom; } diff --git a/src/os2/makefile.va b/src/os2/makefile.va index 02073e611b..7239b43f74 100644 --- a/src/os2/makefile.va +++ b/src/os2/makefile.va @@ -294,6 +294,9 @@ OS2OBJS = \ ..\os2\$D\choice.obj \ ..\os2\$D\clipbrd.obj \ ..\os2\$D\colordlg.obj \ + ..\os2\$D\colour.obj \ + ..\os2\$D\combobox.obj \ + ..\os2\$D\control.obj \ ..\os2\$D\dc.obj \ ..\os2\$D\dialog.obj \ ..\os2\$D\frame.obj \ @@ -311,6 +314,9 @@ OS2LIBOBJS = \ choice.obj \ clipbrd.obj \ colordlg.obj \ + colour.obj \ + combobox.obj \ + control.obj \ dc.obj \ dialog.obj \ frame.obj \ @@ -472,6 +478,9 @@ $(OS2LIBOBJS): copy ..\os2\$D\choice.obj copy ..\os2\$D\clipbrd.obj copy ..\os2\$D\colordlg.obj + copy ..\os2\$D\colour.obj + copy ..\os2\$D\combobox.obj + copy ..\os2\$D\control.obj copy ..\os2\$D\dc.obj copy ..\os2\$D\dialog.obj copy ..\os2\$D\frame.obj diff --git a/src/os2/utils.cpp b/src/os2/utils.cpp index 940bdc21bc..34ae33543a 100644 --- a/src/os2/utils.cpp +++ b/src/os2/utils.cpp @@ -1,56 +1,122 @@ ///////////////////////////////////////////////////////////////////////////// // Name: utils.cpp // Purpose: Various utilities -// Author: AUTHOR +// Author: David Webster // Modified by: -// Created: ??/??/98 +// Created: 09/17/99 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) David Webster +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ -// Note: this is done in utilscmn.cpp now. -// #pragma implementation -// #pragma implementation "utils.h" +// #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now. #endif -#include "wx/setup.h" -#include "wx/utils.h" -#include "wx/app.h" +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP + #include "wx/setup.h" + #include "wx/utils.h" + #include "wx/app.h" + #include "wx/cursor.h" +#endif //WX_PRECOMP + +#include "wx/os2/private.h" +#include "wx/timer.h" +#include "wx/intl.h" + +#define INCL_OS2 +#define INCL_PM #include +#include + +#include "wx/log.h" + +#include #include #include #include +#include #include +#include +#include + +// In the WIN.INI file +static const wxChar WX_SECTION[] = "wxWindows"; +static const wxChar eHOSTNAME[] = "HostName"; +static const wxChar eUSERID[] = "UserId"; +static const wxChar eUSERNAME[] = "UserName"; + +// For the following functions we SHOULD fill in support +// for Windows-NT (which I don't know) as I assume it begin +// a POSIX Unix (so claims MS) that it has some special +// functions beyond those provided by WinSock + // Get full hostname (eg. DoDo.BSn-Germany.crg.de) -bool wxGetHostName(char *buf, int maxSize) +bool wxGetHostName(wxChar *buf, int maxSize) { - // TODO - return FALSE; +#ifdef USE_NET_API + char server[256]; + char computer[256]; + unsigned long ulLevel; + unsigned char* pbBuffer; + unsigned long ulBuffer; + unsigned long* pulTotalAvail; + + NetBios32GetInfo( server + ,computer + ,ulLevel + ,pbBuffer + ,ulBuffer + ,pulTotalAvail + ); + strcpy(buf, server); +#else + wxChar *sysname; + const wxChar *default_host = _T("noname"); + + if ((sysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL) { + GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1); + } else + wxStrncpy(buf, sysname, maxSize - 1); + buf[maxSize] = _T('\0'); +#endif + return *buf ? TRUE : FALSE; } // Get user ID e.g. jacs -bool wxGetUserId(char *buf, int maxSize) +bool wxGetUserId(wxChar *buf, int maxSize) { - // TODO - return FALSE; + return(U32ELOCL(bub, maxSize)); } -// Get user name e.g. AUTHOR -bool wxGetUserName(char *buf, int maxSize) +bool wxGetUserName(wxChar *buf, int maxSize) { - // TODO - return FALSE; +#ifdef USE_NET_API + wxGetUserId(buf, maxSize); +#else + bool ok = GetProfileString(WX_SECTION, eUSERNAME, _T(""), buf, maxSize - 1) != 0; + if ( !ok ) + { + ok = wxGetUserId(buf, maxSize); + } + + if ( !ok ) + { + wxStrncpy(buf, _T("Unknown User"), maxSize); + } +#endif + return TRUE; } int wxKill(long pid, int sig) { - // TODO - return 0; + return 0; } // @@ -58,40 +124,81 @@ int wxKill(long pid, int sig) // bool wxShell(const wxString& command) { - // TODO - return FALSE; + wxChar *shell; + if ((shell = wxGetenv("COMSPEC")) == NULL) + shell = "\\CMD.EXE"; + + wxChar tmp[255]; + if (command != "") + wxSprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command); + else + wxStrcpy(tmp, shell); + + return (wxExecute((wxChar *)tmp, FALSE) != 0); } // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) long wxGetFreeMemory() { - // TODO - return 0; + return (long)GetFreeSpace(0); +} + +// Sleep for nSecs seconds. Attempt a Windows implementation using timers. +static bool inTimer = FALSE; + +class wxSleepTimer: public wxTimer +{ + public: + inline void Notify() + { + inTimer = FALSE; + Stop(); + } +}; + +static wxTimer *wxTheSleepTimer = NULL; + +void wxUsleep(unsigned long milliseconds) +{ + ::DosSleep(milliseconds); } void wxSleep(int nSecs) { - // TODO + if (inTimer) + return; + + wxTheSleepTimer = new wxSleepTimer; + inTimer = TRUE; + wxTheSleepTimer->Start(nSecs*1000); + while (inTimer) + { + if (wxTheApp->Pending()) + wxTheApp->Dispatch(); + } + delete wxTheSleepTimer; + wxTheSleepTimer = NULL; } // Consume all events until no more left void wxFlushEvents() { +// wxYield(); } -// Output a debug message, in a system dependent fashion. -void wxDebugMsg(const char *fmt ...) +// Output a debug mess., in a system dependent fashion. +void wxDebugMsg(const wxChar *fmt ...) { va_list ap; - static char buffer[512]; + static wxChar buffer[512]; if (!wxTheApp->GetWantDebugOutput()) return ; va_start(ap, fmt); - // wvsprintf(buffer,fmt,ap) ; - // TODO: output buffer + sprintf(buffer,fmt,ap) ; + fflush(buffer) ; va_end(ap); } @@ -99,70 +206,117 @@ void wxDebugMsg(const char *fmt ...) // Non-fatal error: pop up message box and (possibly) continue void wxError(const wxString& msg, const wxString& title) { - // TODO + wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg); + if (::WinMessageBox( HWND_DESKTOP + ,NULL + ,(PSZ)wxBuffer + ,(PSZ)WXSTRINGCAST title + ,MB_ICONEXCLAMATION | MB_YESNO + ) == IDNO) wxExit(); } // Fatal error: pop up message box and abort void wxFatalError(const wxString& msg, const wxString& title) { - // TODO + YUint32 rc; + HWND hWnd; + + WinMessageBox( HWND_DESKTOP + ,hWnd + ,rMsg.Data() + ,rTitle.Data() + ,0 + ,MB_NOICON | MB_OK + ); + DosExit(EXIT_PROCESS, rc); } // Emit a beeeeeep void wxBell() { - // TODO + DosBeep(1000,1000); // 1kHz during 1 sec. } +// Chris Breeze 27/5/98: revised WIN32 code to +// detect WindowsNT correctly int wxGetOsVersion(int *majorVsn, int *minorVsn) { - // TODO - return 0; + ULONG aulSysInfo[QSV_MAX] = {0}; + + if (DosQuerySysInfo( 1L + ,QSV_MAX + ,(PVOID)aulSysInfo + ,sizeof(ULONG) * QSV_MAX + )) + { + *majorVsn = aulSysInfo[QSV_VERSION_MAJOR]; + *minorVsn = aulSysInfo[QSV_VERSION_MINOR]; + return wxWINDOWS_OS2; + } + return wxWINDOWS; // error if we get here, return generic value } // Reading and writing resources (eg WIN.INI, .Xdefaults) #if wxUSE_RESOURCES bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file) { - // TODO - return FALSE; + if (file != "") + return (WritePrivateProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)value, (PCSZ)WXSTRINGCAST file) != 0); + else + return (WriteProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)WXSTRINGCAST value) != 0); } bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file) { - char buf[50]; - sprintf(buf, "%.4f", value); + wxChar buf[50]; + wxSprintf(buf, "%.4f", value); return wxWriteResource(section, entry, buf, file); } bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file) { - char buf[50]; - sprintf(buf, "%ld", value); + wxChar buf[50]; + wxSprintf(buf, "%ld", value); return wxWriteResource(section, entry, buf, file); } bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file) { - char buf[50]; - sprintf(buf, "%d", value); + wxChar buf[50]; + wxSprintf(buf, "%d", value); return wxWriteResource(section, entry, buf, file); } -bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file) +bool wxGetResource(const wxString& section, const wxString& entry, wxChar **value, const wxString& file) { - // TODO - return FALSE; -} + static const wxChar defunkt[] = "$$default"; + if (file != "") + { + int n = GetPrivateProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)defunkt, + (PSZ)wxBuffer, 1000, (PCSZ)WXSTRINGCAST file); + if (n == 0 || wxStrcmp(wxBuffer, defunkt) == 0) + return FALSE; + } + else + { + int n = GetProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (LPCTSTR)defunkt, + (PSZ)wxBuffer, 1000); + if (n == 0 || wxStrcmp(wxBuffer, defunkt) == 0) + return FALSE; + } + if (*value) delete[] (*value); + *value = copystring(wxBuffer); + return TRUE; + } bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file) { - char *s = NULL; - bool succ = wxGetResource(section, entry, (char **)&s, file); + wxChar *s = NULL; + bool succ = wxGetResource(section, entry, (wxChar **)&s, file); if (succ) { - *value = (float)strtod(s, NULL); + *value = (float)wxStrtod(s, NULL); delete[] s; return TRUE; } @@ -171,11 +325,11 @@ bool wxGetResource(const wxString& section, const wxString& entry, float *value, bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file) { - char *s = NULL; - bool succ = wxGetResource(section, entry, (char **)&s, file); + wxChar *s = NULL; + bool succ = wxGetResource(section, entry, (wxChar **)&s, file); if (succ) { - *value = strtol(s, NULL, 10); + *value = wxStrtol(s, NULL, 10); delete[] s; return TRUE; } @@ -184,89 +338,266 @@ bool wxGetResource(const wxString& section, const wxString& entry, long *value, bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file) { - char *s = NULL; - bool succ = wxGetResource(section, entry, (char **)&s, file); + wxChar *s = NULL; + bool succ = wxGetResource(section, entry, (wxChar **)&s, file); if (succ) { - *value = (int)strtol(s, NULL, 10); - delete[] s; + *value = (int)wxStrtol(s, NULL, 10); + delete[] s; return TRUE; } else return FALSE; } #endif // wxUSE_RESOURCES -static int wxBusyCursorCount = 0; +// --------------------------------------------------------------------------- +// helper functions for showing a "busy" cursor +// --------------------------------------------------------------------------- + +HCURSOR gs_wxBusyCursor = 0; // new, busy cursor +HCURSOR gs_wxBusyCursorOld = 0; // old cursor +static int gs_wxBusyCursorCount = 0; // Set the cursor to the busy cursor for all windows void wxBeginBusyCursor(wxCursor *cursor) { - wxBusyCursorCount ++; - if (wxBusyCursorCount == 1) - { - // TODO - } - else - { - // TODO - } + if ( gs_wxBusyCursorCount++ == 0 ) + { + gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR(); + ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor); + } + //else: nothing to do, already set } // Restore cursor to normal void wxEndBusyCursor() { - if (wxBusyCursorCount == 0) - return; - - wxBusyCursorCount --; - if (wxBusyCursorCount == 0) - { - // TODO - } + wxCHECK_RET( gs_wxBusyCursorCount > 0, + "no matching wxBeginBusyCursor() for wxEndBusyCursor()"); + + if ( --gs_wxBusyCursorCount == 0 ) + { + ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld); + gs_wxBusyCursorOld = 0; + } } // TRUE if we're between the above two calls bool wxIsBusy() { - return (wxBusyCursorCount > 0); -} + return (gs_wxBusyCursorCount > 0); +} + +// --------------------------------------------------------------------------- +const wxChar* wxGetHomeDir(wxString *pstr) +{ + wxString& strDir = *pstr; -char *wxGetUserHome (const wxString& user) + // OS/2 has no idea about home, + // so use the working directory instead? + + // 256 was taken from os2def.h +#ifndef MAX_PATH +# define MAX_PATH 256 +#endif + + + char DirName[256]; + ULONG DirLen; + + ::DosQueryCurrentDir( 0, DirName, &DirLen); + strDir = DirName; + return strDir.c_str(); +} + +// Hack for MS-DOS +wxChar *wxGetUserHome (const wxString& user) { - // TODO - return NULL; + wxChar *home; + wxString user1(user); + + if (user1 != _T("")) { + wxChar tmp[64]; + if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) { + // Guests belong in the temp dir + if (wxStricmp(tmp, "annonymous") == 0) { + if ((home = wxGetenv("TMP")) != NULL || + (home = wxGetenv("TMPDIR")) != NULL || + (home = wxGetenv("TEMP")) != NULL) + return *home ? home : (wxChar*)_T("\\"); + } + if (wxStricmp(tmp, WXSTRINGCAST user1) == 0) + user1 = _T(""); + } + } + if (user1 == _T("")) + if ((home = wxGetenv("HOME")) != NULL) + { + wxStrcpy(wxBuffer, home); + Unix2DosFilename(wxBuffer); + return wxBuffer; + } + return NULL; // No home known! } // Check whether this window wants to process messages, e.g. Stop button // in long calculations. bool wxCheckForInterrupt(wxWindow *wnd) { - // TODO - return FALSE; + if(wnd){ + QMSG msg; + HAB hab; + HWND hwndFilter; + + HWND win= (HWND) wnd->GetHWND(); + while(::WinPeekMsg(hab,&msg,hwndFilter,0,0,PM_REMOVE)) + { + ::WinDispatchMsg( hab, &qmsg ); + } + return TRUE;//*** temporary? + } + else{ + wxFAIL_MSG("wnd==NULL !!!"); + + return FALSE;//*** temporary? + } +} + +wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType) +{ + wxChar *s = NULL; + +/* +* How to in PM? +* +* #if !defined(__WIN32__) || defined(__TWIN32__) +* HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType); +* #else +* #ifdef UNICODE +* HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType); +* #else +* HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType); +* #endif +* #endif +* +* if (hResource == 0) +* return NULL; +* HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource); +* if (hData == 0) +* return NULL; +* wxChar *theText = (wxChar *)LockResource(hData); +* if (!theText) +* return NULL; +*/ + s = copystring(theText); + + return s; } void wxGetMousePosition( int* x, int* y ) { - // TODO + POINT pt; + GetCursorPos( & pt ); + *x = pt.x; + *y = pt.y; }; // Return TRUE if we have a colour display bool wxColourDisplay() { - // TODO - return TRUE; + bool flag; + // TODO: use DosQueryDevCaps to figure it out + return flag; } // Returns depth of screen int wxDisplayDepth() { - // TODO - return 0; + HDC hDc = ::WinOpenWindowDC((HWND)NULL); + long lArray[CAPS_COLOR_BITCOUNT]; + int nPlanes; + int nBitsPerPixel; + int nDepth; + + if(DevQueryCaps( hDc + ,CAPS_FAMILY + ,CAPS_COLOR_BITCOUNT + ,lArray + )) + { + nPlanes = (int)lArray[CAPS_COLOR_PLANES]; + nBitsPerPixel = (int)lArray[CAPS_COLOR_BITCOUNT]; + nDepth = nPlanes * nBitsPerPixel; + } + DevCloseDC(hDc); + return (depth); } // Get size of display void wxDisplaySize(int *width, int *height) { - // TODO + HDC hDc = ::WinOpenWindowDC((HWND)NULL); + long lArray[CAPS_HEIGHT]; + + if(DevQueryCaps( hDc + ,CAPS_FAMILY + ,CAPS_HEIGHT + ,lArray + )) + { + *pWidth = (int)lArray[CAPS_WIDTH]; + *pHeight = (int)lArray[CAPS_HEIGHT]; + } + DevCloseDC(hDc); +} + +bool wxDirExists(const wxString& dir) +{ + // TODO: Control program file stuff + return TRUE; +} + +// --------------------------------------------------------------------------- +// window information functions +// --------------------------------------------------------------------------- + +wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd) +{ + wxString str; + long len = ::WinQueryWindowTextLength((HWND)hWnd) + 1; + ::WinQueryWindowText((HWND)hWnd, str.GetWriteBuf((int)len), len); + str.UngetWriteBuf(); + + return str; +} + +wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd) +{ + wxString str; + + int len = 256; // some starting value + + for ( ;; ) + { + int count = ::WinQueryClassName((HWND)hWnd, str.GetWriteBuf(len), len); + + str.UngetWriteBuf(); + if ( count == len ) + { + // the class name might have been truncated, retry with larger + // buffer + len *= 2; + } + else + { + break; + } + } + return str; +} + +WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd) +{ + return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID); }