From: David Webster Date: Fri, 30 Aug 2002 13:37:52 +0000 (+0000) Subject: Lots of updates fixing radiobox processing, checkboxes and add notebook control. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f289196b3a47487984ed01ee108476bc227c4d5a?hp=07901ec945462644af6efef53a5d600813a0b038 Lots of updates fixing radiobox processing, checkboxes and add notebook control. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16861 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/os2/notebook.h b/include/wx/os2/notebook.h index 2a1b3b95a1..68fc28013b 100644 --- a/include/wx/os2/notebook.h +++ b/include/wx/os2/notebook.h @@ -8,155 +8,202 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_NOTEBOOK_H_ -#define _WX_NOTEBOOK_H_ +#ifndef _NOTEBOOK_H +#define _NOTEBOOK_H -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/dynarray.h" -#include "wx/string.h" -#include "wx/notebook.h" +#if wxUSE_NOTEBOOK // ---------------------------------------------------------------------------- -// types +// headers // ---------------------------------------------------------------------------- -// fwd declarations -class WXDLLEXPORT wxImageList; -class WXDLLEXPORT wxWindow; - -// array of notebook pages -WX_DEFINE_ARRAY(wxNotebookPage *, wxArrayNBPages); +#include "wx/control.h" // ---------------------------------------------------------------------------- // wxNotebook // ---------------------------------------------------------------------------- -// FIXME this class should really derive from wxTabCtrl, but the interface is not -// exactly the same, so I can't do it right now and instead we reimplement -// part of wxTabCtrl here class WXDLLEXPORT wxNotebook : public wxNotebookBase { public: - // ctors - // ----- - // default for dynamic class - wxNotebook(); - // the same arguments as for wxControl (@@@ any special styles?) - wxNotebook(wxWindow *parent, - wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxString& name = "notebook"); - // Create() function - bool Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxString& name = "notebook"); - // dtor - ~wxNotebook(); - - // accessors - // --------- - // get number of pages in the dialog - int GetPageCount() const; - - // set the currently selected page, return the index of the previously + // + // Ctors + // ----- + // Default for dynamic class + // + wxNotebook(); + + // + // the same arguments as for wxControl + // + wxNotebook( wxWindow* pParent + ,wxWindowID vId + ,const wxPoint& rPos = wxDefaultPosition + ,const wxSize& rSize = wxDefaultSize + ,long lStyle = 0 + ,const wxString& rsName = "notebook" + ); + + bool Create( wxWindow* pParent + ,wxWindowID vId + ,const wxPoint& rPos = wxDefaultPosition + ,const wxSize& rSize = wxDefaultSize + ,long lStyle = 0 + ,const wxString& rsName = "notebook" + ); + + // + // Accessors + // --------- + // Get number of pages in the dialog + // + int GetPageCount(void) const; + + // + // Set the currently selected page, return the index of the previously // selected one (or -1 on error) // NB: this function will _not_ generate wxEVT_NOTEBOOK_PAGE_xxx events - int SetSelection(int nPage); - // cycle thru the tabs - void AdvanceSelection(bool bForward = TRUE); - // get the currently selected page - int GetSelection() const { return m_nSelection; } - - // set/get the title of a page - bool SetPageText(int nPage, const wxString& strText); - wxString GetPageText(int nPage) const; - - // image list stuff: each page may have an image associated with it. All - // the images belong to an image list, so you have to - // 1) create an image list - // 2) associate it with the notebook - // 3) set for each page it's image + // + int SetSelection(int nPage); + + // + // Get the currently selected page + // + inline int GetSelection(void) const { return m_nSelection; } + + // + // Set/Get the title of a page + // + bool SetPageText( int nPage + ,const wxString& sStrText + ); + wxString GetPageText(int nPage) const; + + // + // Image list stuff: each page may have an image associated with it. All + // the images belong to an image list, so you have to + // 1) create an image list + // 2) associate it with the notebook + // 3) set for each page it's image // associate image list with a control - void SetImageList(wxImageList* imageList); - // get pointer (may be NULL) to the associated image list - wxImageList* GetImageList() const { return m_pImageList; } - - // sets/returns item's image index in the current image list - int GetPageImage(int nPage) const; - bool SetPageImage(int nPage, int nImage); - - // currently it's always 1 because wxGTK doesn't support multi-row + // + void SetImageList(wxImageList* pImageList); + + // + // Sets/returns item's image index in the current image list + // + int GetPageImage(int nPage) const; + bool SetPageImage( int nPage + ,int nImage + ); + + // + // Currently it's always 1 because wxGTK doesn't support multi-row // tab controls - int GetRowCount() const; + // + int GetRowCount(void) const; - // control the appearance of the notebook pages + // + // control the appearance of the notebook pages // set the size (the same for all pages) - void SetPageSize(const wxSize& size); - // set the padding between tabs (in pixels) - void SetPadding(const wxSize& padding); - - // operations - // ---------- - // remove one page from the notebook - bool DeletePage(int nPage); - // remove one page from the notebook, without deleting - bool RemovePage(int nPage); - // remove all pages - bool DeleteAllPages(); - // adds a new page to the notebook (it will be deleted ny the notebook, + // + void SetPageSize(const wxSize& rSize); + + // + // Set the padding between tabs (in pixels) + // + void SetPadding(const wxSize& rPadding); + + // + // Operations + // ---------- + // Remove all pages + // + bool DeleteAllPages(void); + + // + // Adds a new page to the notebook (it will be deleted ny the notebook, // don't delete it yourself). If bSelect, this page becomes active. - bool AddPage(wxNotebookPage *pPage, - const wxString& strText, - bool bSelect = FALSE, - int imageId = -1); - // the same as AddPage(), but adds it at the specified position - bool InsertPage(int nPage, - wxNotebookPage *pPage, - const wxString& strText, - bool bSelect = FALSE, - int imageId = -1); - // get the panel which represents the given page - wxNotebookPage *GetPage(int nPage) { return m_aPages[nPage]; } - + // + bool AddPage( wxNotebookPage* pPage + ,const wxString& rsStrText + ,bool bSelect = FALSE + ,int nImageId = -1 + ); + + // + // The same as AddPage(), but adds it at the specified position + // + bool InsertPage( int nPage + ,wxNotebookPage* pPage + ,const wxString& rsStrText + ,bool bSelect = FALSE + ,int nImageId = -1 + ); + + // // Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH // style. - void SetTabSize(const wxSize& sz); + // + void SetTabSize(const wxSize& rSize); + + // + // Callbacks + // --------- + // + void OnSize(wxSizeEvent& rEvent); + void OnSelChange(wxNotebookEvent& rEvent); + void OnSetFocus(wxFocusEvent& rEvent); + void OnNavigationKey(wxNavigationKeyEvent& rEvent); + + // + // Base class virtuals + // ------------------- + // + virtual bool OS2OnScroll( int nOrientation + ,WXWORD wSBCode + ,WXWORD wPos + ,WXHWND hControl + ); + virtual void SetConstraintSizes(bool bRecurse = TRUE); + virtual bool DoPhase(int nPhase); + +protected: + // + // Common part of all ctors + // + void Init(void); - // callbacks - // --------- - void OnSize(wxSizeEvent& event); - void OnSelChange(wxNotebookEvent& event); - void OnSetFocus(wxFocusEvent& event); - void OnNavigationKey(wxNavigationKeyEvent& event); + // + // Translate wxWin styles to the PM ones + // + virtual WXDWORD OS2GetStyle( long lFlags + ,WXDWORD* pwExstyle = NULL + ) const; - // base class virtuals - // ------------------- - virtual bool OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); - virtual void SetConstraintSizes(bool recurse = TRUE); - virtual bool DoPhase(int nPhase); + // + // Remove one page from the notebook, without deleting + // + virtual wxNotebookPage* DoRemovePage(int nPage); -protected: - // common part of all ctors - void Init(); + // + // Helper functions + // + void ChangePage( int nOldSel + ,int nSel + ); // change pages + + int m_nSelection; // The current selection (-1 if none) - // helper functions - void ChangePage(int nOldSel, int nSel); // change pages +private: + wxArrayLong m_alPageId; + int m_nTabSize; // holds the largest tab size - wxImageList *m_pImageList; // we can have an associated image list - wxArrayNBPages m_aPages; // array of pages + DECLARE_DYNAMIC_CLASS(wxNotebook) + DECLARE_EVENT_TABLE() +}; // end of CLASS wxNotebook - int m_nSelection; // the current selection (-1 if none) +#endif // wxUSE_NOTEBOOK - DECLARE_DYNAMIC_CLASS(wxNotebook) - DECLARE_EVENT_TABLE() -}; +#endif // _NOTEBOOK_H -#endif // _WX_NOTEBOOK_H_ diff --git a/include/wx/os2/window.h b/include/wx/os2/window.h index 3d1e43bf7d..04aa11e48d 100644 --- a/include/wx/os2/window.h +++ b/include/wx/os2/window.h @@ -227,6 +227,10 @@ public: void OnIdle(wxIdleEvent& rEvent); public: + // For hidden notebook pages, always TRUE for everything else + bool IsActivePage(void) const { return m_bIsActivePage; } + void SetActivePage(bool bActive) { m_bIsActivePage = bActive; } + // For implementation purposes - sometimes decorations make the client area // smaller virtual wxPoint GetClientAreaOrigin(void) const; @@ -607,6 +611,7 @@ private: HWND m_hWndScrollBarHorz; HWND m_hWndScrollBarVert; SWP m_vWinSwp; + bool m_bIsActivePage; // Virtual function hiding supression inline virtual bool Reparent(wxWindowBase* pNewParent) diff --git a/src/os2/checkbox.cpp b/src/os2/checkbox.cpp index 40eac8c614..bfc9f835ad 100644 --- a/src/os2/checkbox.cpp +++ b/src/os2/checkbox.cpp @@ -29,6 +29,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxBitmapCheckBox, wxCheckBox) +extern void wxAssociateWinWithHandle( HWND hWnd + ,wxWindowOS2* pWin + ); + // ============================================================================ // implementation // ============================================================================ @@ -64,6 +68,9 @@ bool wxCheckBox::Create( , const wxString& rsName ) { + LONG lColor; + bool bOk; + if (!CreateControl( pParent ,vId ,rPos @@ -76,17 +83,27 @@ bool wxCheckBox::Create( )) return FALSE; + long osStyle = BS_AUTOCHECKBOX | WS_TABSTOP | WS_VISIBLE; - return OS2CreateControl( wxT("BUTTON") - ,osStyle - ,rPos - ,rSize - ,rsLabel - ,0 - ); + bOk = OS2CreateControl( wxT("BUTTON") + ,osStyle + ,rPos + ,rSize + ,rsLabel + ,0 + ); + m_backgroundColour = pParent->GetBackgroundColour(); + lColor = (LONG)m_backgroundColour.GetPixel(); + ::WinSetPresParam( m_hWnd + ,PP_BACKGROUNDCOLOR + ,sizeof(LONG) + ,(PVOID)&lColor + ); + wxAssociateWinWithHandle(m_hWnd, this); + return bOk; } // end of wxCheckBox::Create void wxCheckBox::SetLabel( diff --git a/src/os2/control.cpp b/src/os2/control.cpp index a7d56cb07d..6b4a38bc8b 100644 --- a/src/os2/control.cpp +++ b/src/os2/control.cpp @@ -105,10 +105,7 @@ bool wxControl::OS2CreateControl( ) { bool bWant3D = FALSE; - int nX = rPos.x == -1 ? 0 : rPos.x; - int nY = rPos.y == -1 ? 0 : rPos.y; - int nW = rSize.x == -1 ? 0 : rSize.x; - int nH = rSize.y == -1 ? 0 : rSize.y; + // // Doesn't do anything at all under OS/2 // @@ -134,6 +131,8 @@ bool wxControl::OS2CreateControl( zClass = WC_STATIC; else if ((strcmp(zClassname, "BUTTON")) == 0) zClass = WC_BUTTON; + else if ((strcmp(zClassname, "NOTEBOOK")) == 0) + zClass = WC_NOTEBOOK; dwStyle |= WS_VISIBLE; m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle @@ -170,8 +169,11 @@ bool wxControl::OS2CreateControl( InheritAttributes(); SetXComp(0); SetYComp(0); - if (nW == 0 || nH == 0) - SetBestSize(rSize); + SetSize( rPos.x + ,rPos.y + ,rSize.x + ,rSize.y + ); return TRUE; } // end of wxControl::OS2CreateControl diff --git a/src/os2/fontutil.cpp b/src/os2/fontutil.cpp index 01b7d7b4ff..8437a71312 100644 --- a/src/os2/fontutil.cpp +++ b/src/os2/fontutil.cpp @@ -640,12 +640,12 @@ void wxOS2SelectMatchingFontByName( // pFattrs->usRecordLength = sizeof(FATTRS); // Sets size of structure pFattrs->lMatch = pFM[nIndex].lMatch; // Force match - pFattrs->idRegistry = 0; // Registry - pFattrs->usCodePage = 0; // Match proper CodePage - pFattrs->fsFontUse = 0; // Use only outline fonts - pFattrs->fsType = 0; // Use only outline fonts - pFattrs->lMaxBaselineExt = 0; // Use only outline fonts - pFattrs->lAveCharWidth = 0; // Use only outline fonts + pFattrs->idRegistry = 0; + pFattrs->usCodePage = 0; + pFattrs->fsFontUse = 0; + pFattrs->fsType = 0; + pFattrs->lMaxBaselineExt = 0; + pFattrs->lAveCharWidth = 0; wxStrcpy(pFattrs->szFacename, pFM[nIndex].szFacename); if (pFont->GetWeight() == wxNORMAL) pFattrs->fsSelection = 0; diff --git a/src/os2/notebook.cpp b/src/os2/notebook.cpp index a32e88326e..7cfd92ab12 100644 --- a/src/os2/notebook.cpp +++ b/src/os2/notebook.cpp @@ -12,46 +12,35 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#if wxUSE_NOTEBOOK + // wxWindows #ifndef WX_PRECOMP - #include + #include "wx/string.h" #endif // WX_PRECOMP -#include -#include -#include -#include -#include - -#include +#include "wx/log.h" +#include "wx/imaglist.h" +#include "wx/event.h" +#include "wx/control.h" +#include "wx/notebook.h" +#include "wx/os2/private.h" // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- + // check that the page index is valid #define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount())) // hide the ugly cast -#define m_hwnd (HWND)GetHWND() +#define m_hWnd (HWND)GetHWND() // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- -// This is a work-around for missing defines in gcc-2.95 headers -#ifndef TCS_RIGHT - #define TCS_RIGHT 0x0002 -#endif - -#ifndef TCS_VERTICAL - #define TCS_VERTICAL 0x0080 -#endif - -#ifndef TCS_BOTTOM - #define TCS_BOTTOM TCS_RIGHT -#endif - // ---------------------------------------------------------------------------- // event table // ---------------------------------------------------------------------------- @@ -77,440 +66,845 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent) // wxNotebook construction // ---------------------------------------------------------------------------- -// common part of all ctors +// +// Common part of all ctors +// void wxNotebook::Init() { - m_pImageList = NULL; + m_imageList = NULL; m_nSelection = -1; -} + m_nTabSize = 0; +} // end of wxNotebook::Init -// default for dynamic class +// +// Default for dynamic class +// wxNotebook::wxNotebook() { Init(); -} - -// the same arguments as for wxControl -wxNotebook::wxNotebook(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +} // end of wxNotebook::wxNotebook + +// +// The same arguments as for wxControl +// +wxNotebook::wxNotebook( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, long lStyle +, const wxString& rsName +) { Init(); - - Create(parent, id, pos, size, style, name); -} - + Create( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,rsName + ); +} // end of wxNotebook::wxNotebook + +// // Create() function -bool wxNotebook::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +// +bool wxNotebook::Create( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, long lStyle +, const wxString& rsName +) { - // base init - if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) - return FALSE; - - // colors and font -// TODO: m_backgroundColour = wxColour(GetSysColor(COLOR_BTNFACE)); - m_foregroundColour = *wxBLACK ; - - // TODO: -/* - // style - m_windowStyle = style | wxTAB_TRAVERSAL; - - long tabStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | TCS_TABS; - - if (m_windowStyle & wxCLIP_CHILDREN) - tabStyle |= WS_CLIPCHILDREN; - if ( m_windowStyle & wxTC_MULTILINE ) - tabStyle |= TCS_MULTILINE; - if ( m_windowStyle & wxBORDER ) - tabStyle &= WS_BORDER; - if (m_windowStyle & wxNB_FIXEDWIDTH) - tabStyle |= TCS_FIXEDWIDTH ; - if (m_windowStyle & wxNB_BOTTOM) - tabStyle |= TCS_RIGHT; - if (m_windowStyle & wxNB_LEFT) - tabStyle |= TCS_VERTICAL; - if (m_windowStyle & wxNB_RIGHT) - tabStyle |= TCS_VERTICAL|TCS_RIGHT; - - - if ( !MSWCreate(GetId(), GetParent(), WC_TABCONTROL, - this, NULL, pos.x, pos.y, size.x, size.y, - tabStyle, NULL, 0) ) - { - return FALSE; - } - - // Not all compilers recognise SetWindowFont - ::SendMessage(GetHwnd(), WM_SETFONT, - (WPARAM)::GetStockObject(DEFAULT_GUI_FONT), TRUE); - - - if ( parent != NULL ) - parent->AddChild(this); -*/ - SubclassWin(m_hWnd); - - return FALSE; -} - -// dtor -wxNotebook::~wxNotebook() + // + // Base init + // + if (!CreateControl( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,wxDefaultValidator + ,rsName + )) + return FALSE; + + // + // Notebook, so explicitly specify 0 as last parameter + // + if (!OS2CreateControl( "NOTEBOOK" + ,_T("") + ,rPos + ,rSize + ,lStyle | wxTAB_TRAVERSAL + )) + return FALSE; + + SetBackgroundColour(wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE))); + return TRUE; +} // end of wxNotebook::Create + +WXDWORD wxNotebook::OS2GetStyle ( + long lStyle +, WXDWORD* pdwExstyle +) const { -} + WXDWORD dwTabStyle = wxControl::OS2GetStyle( lStyle + ,pdwExstyle + ); + + dwTabStyle |= WS_TABSTOP | BKS_SOLIDBIND | BKS_ROUNDEDTABS | BKS_TABTEXTCENTER; + + if (lStyle & wxNB_BOTTOM) + dwTabStyle |= BKS_MAJORTABBOTTOM | BKS_BACKPAGESBL; + else if (lStyle & wxNB_RIGHT) + dwTabStyle |= BKS_MAJORTABRIGHT | BKS_BACKPAGESBR; + else if (lStyle & wxNB_LEFT) + dwTabStyle |= BKS_MAJORTABLEFT | BKS_BACKPAGESTL; + else // default to top + dwTabStyle |= BKS_MAJORTABTOP | BKS_BACKPAGESTR; + + // + // Ex style + // + if (pdwExstyle ) + { + // + // Note that we never want to have the default WS_EX_CLIENTEDGE style + // as it looks too ugly for the notebooks + // + *pdwExstyle = 0; + } + return dwTabStyle; +} // end of wxNotebook::OS2GetStyle // ---------------------------------------------------------------------------- // wxNotebook accessors // ---------------------------------------------------------------------------- + int wxNotebook::GetPageCount() const { - return m_aPages.Count(); -} + int nPageInternal = m_pages.Count(); + int nPageAPI = (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END); + + // + // Consistency check + // + wxASSERT((int)m_pages.Count() == (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END)); + return m_pages.Count(); +} // end of wxNotebook::GetPageCount int wxNotebook::GetRowCount() const { - // TODO - return 0; -} - -int wxNotebook::SetSelection(int nPage) + return (int)::WinSendMsg( GetHWND() + ,BKM_QUERYPAGECOUNT + ,(MPARAM)0 + ,(MPARAM)BKA_MAJOR + ); +} // end of wxNotebook::GetRowCount + +int wxNotebook::SetSelection( + int nPage +) { wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") ); + int nOldPage = GetSelection(); + + ChangePage( m_nSelection + ,nPage + ); + + ULONG ulPageId = (ULONG)m_alPageId[nPage]; + + ::WinSendMsg( GetHWND() + ,BKM_TURNTOPAGE + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,(MPARAM)0 + ); + m_nSelection = nPage; + return nPage; +} // end of wxNotebook::SetSelection + +bool wxNotebook::SetPageText( + int nPage +, const wxString& rsStrText +) +{ + wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") ); - ChangePage(m_nSelection, nPage); - // TODO - return 0; -} + ULONG ulPageId = (ULONG)m_alPageId[nPage]; -void wxNotebook::AdvanceSelection(bool bForward) -{ - int nSel = GetSelection(); - int nMax = GetPageCount() - 1; - if ( bForward ) - SetSelection(nSel == nMax ? 0 : nSel + 1); - else - SetSelection(nSel == 0 ? nMax : nSel - 1); -} + return (bool)::WinSendMsg( m_hWnd + ,BKM_SETTABTEXT + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,MPFROMP((PSZ)rsStrText.c_str()) + ); +} // end of wxNotebook::SetPageText -bool wxNotebook::SetPageText(int nPage, const wxString& strText) +wxString wxNotebook::GetPageText ( + int nPage +) const { - wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") ); + BOOKTEXT vBookText; + wxChar zBuf[256]; + wxString sStr; + ULONG ulRc; - // TODO - return FALSE; -} - -wxString wxNotebook::GetPageText(int nPage) const -{ wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") ); - // TODO - return wxString(""); -} -int wxNotebook::GetPageImage(int nPage) const + ULONG ulPageId = (ULONG)m_alPageId[nPage]; + + memset(&vBookText, '\0', sizeof(BOOKTEXT)); + vBookText.textLen = 0; // This will get the length + ulRc = LONGFROMMR(::WinSendMsg( m_hWnd + ,BKM_QUERYTABTEXT + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,MPFROMP(&vBookText) + )); + if (ulRc == BOOKERR_INVALID_PARAMETERS || ulRc == 0L) + { + if (ulRc == BOOKERR_INVALID_PARAMETERS) + { + wxLogError(wxT("Invalid Page Id for page text querry.")); + } + return wxEmptyString; + } + vBookText.textLen = ulRc + 1; // To get the null terminator + vBookText.pString = zBuf; + + // + // Now get the actual text + // + ulRc = LONGFROMMR(::WinSendMsg( m_hWnd + ,BKM_QUERYTABTEXT + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,MPFROMP(&vBookText) + )); + if (ulRc == BOOKERR_INVALID_PARAMETERS || ulRc == 0L) + { + return wxEmptyString; + } + if (ulRc > 255L) + ulRc = 255L; + + vBookText.pString[ulRc] = '\0'; + sStr = vBookText.pString; + return sStr; +} // end of wxNotebook::GetPageText + +int wxNotebook::GetPageImage ( + int nPage +) const { wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") ); - // TODO - return 0; -} + // + // For OS/2 just return the page + // + return nPage; +} // end of wxNotebook::GetPageImage -bool wxNotebook::SetPageImage(int nPage, int nImage) +bool wxNotebook::SetPageImage ( + int nPage +, int nImage +) { - wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") ); + wxBitmap* pBitmap = (wxBitmap*)m_imageList->GetBitmap(nImage); - // TODO - return FALSE; -} -void wxNotebook::SetImageList(wxImageList* imageList) -{ - m_pImageList = imageList; - // TODO -} + ULONG ulPageId = (ULONG)m_alPageId[nPage]; -void wxNotebook::SetTabSize(const wxSize& sz) + return (bool)::WinSendMsg( GetHWND() + ,BKM_SETTABBITMAP + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,(MPARAM)pBitmap->GetHBITMAP() + ); +} // end of wxNotebook::SetPageImage + +void wxNotebook::SetImageList ( + wxImageList* WXUNUSED(pImageList) +) { - // TODO -} + // + // Does nothing under OS/2 + // +} // end of wxNotebook::SetImageList // ---------------------------------------------------------------------------- -// wxNotebook operations +// wxNotebook size settings // ---------------------------------------------------------------------------- - -void wxNotebook::SetPageSize(const wxSize& size) +void wxNotebook::SetPageSize ( + const wxSize& rSize +) { - // transform the page size into the notebook size - RECT rc; - rc.xLeft = rc.yTop = 0; - rc.xRight = size.x; - rc.yBottom = size.y; - -// TabCtrl_AdjustRect(GetHwnd(), TRUE, &rc); - - // and now set it - SetSize(rc.xRight - rc.xLeft, rc.yBottom - rc.yTop); -} - -void wxNotebook::SetPadding(const wxSize& padding) + RECTL vRect; + + // + // Transform the page size into the notebook size + // + vRect.xLeft = vRect.yTop = 0; + vRect.xRight = rSize.x; + vRect.yBottom = rSize.y; + + + // + // And now set it + // + SetSize( vRect.xRight - vRect.xLeft + ,vRect.yBottom - vRect.yTop + ); +} // end of wxNotebook::SetPageSize + +void wxNotebook::SetPadding ( + const wxSize& WXUNUSED(rPadding) +) { -// TabCtrl_SetPadding(GetHwnd(), padding.x, padding.y); -} + // + // No padding in OS/2 + // +} // end of wxNotebook::SetPadding + +void wxNotebook::SetTabSize ( + const wxSize& rSize +) +{ + ::WinSendMsg( GetHWND() + ,BKM_SETDIMENSIONS + ,MPFROM2SHORT( (USHORT)rSize.x + ,(USHORT)rSize.y + ) + ,(MPARAM)BKA_MAJORTAB + ); +} // end of wxNotebook::SetTabSize + +// ---------------------------------------------------------------------------- +// wxNotebook operations +// ---------------------------------------------------------------------------- -// remove one page from the notebook -bool wxNotebook::DeletePage(int nPage) +// +// Remove one page from the notebook, without deleting +// +wxNotebookPage* wxNotebook::DoRemovePage ( + int nPage +) { - wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") ); + wxNotebookPage* pPageRemoved = wxNotebookBase::DoRemovePage(nPage); - // TODO: delete native widget page + if (!pPageRemoved) + return NULL; - delete m_aPages[nPage]; - m_aPages.RemoveAt(nPage); - return TRUE; -} + ULONG ulPageId = (ULONG)m_alPageId[nPage]; -// remove one page from the notebook, without deleting the window -bool wxNotebook::RemovePage(int nPage) -{ - wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") ); + ::WinSendMsg( GetHWND() + ,BKM_DELETEPAGE + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,(MPARAM)BKA_TAB + ); + if (m_pages.IsEmpty()) + { + // + // No selection any more, the notebook becamse empty + // + m_nSelection = -1; + } + else // notebook still not empty + { + // + // Change the selected page if it was deleted or became invalid + // + int nSelNew; - m_aPages.RemoveAt(nPage); + if (m_nSelection == GetPageCount()) + { + // + // Last page deleted, make the new last page the new selection + // + nSelNew = m_nSelection - 1; + } + else if (nPage <= m_nSelection) + { + // + // We must show another page, even if it has the same index + // + nSelNew = m_nSelection; + } + else // nothing changes for the currently selected page + { + nSelNew = -1; + + // + // We still must refresh the current page: this needs to be done + // for some unknown reason if the tab control shows the up-down + // control (i.e. when there are too many pages) -- otherwise after + // deleting a page nothing at all is shown + // + m_pages[m_nSelection]->Refresh(); + } - return TRUE; -} + if (nSelNew != -1) + { + // + // m_nSelection must be always valid so reset it before calling + // SetSelection() + // + m_nSelection = -1; + SetSelection(nSelNew); + } + } + return pPageRemoved; +} // end of wxNotebook::DoRemovePage -// remove all pages +// +// Remove all pages +// bool wxNotebook::DeleteAllPages() { - // TODO: delete native widget pages - - int nPageCount = GetPageCount(); - int nPage; - for ( nPage = 0; nPage < nPageCount; nPage++ ) - delete m_aPages[nPage]; - - m_aPages.Clear(); - + int nPageCount = GetPageCount(); + int nPage; + + for (nPage = 0; nPage < nPageCount; nPage++) + delete m_pages[nPage]; + m_pages.Clear(); + ::WinSendMsg( GetHWND() + ,BKM_DELETEPAGE + ,(MPARAM)0 + ,(MPARAM)BKA_ALL + ); + m_nSelection = -1; return TRUE; -} - -// add a page to the notebook -bool wxNotebook::AddPage(wxNotebookPage *pPage, - const wxString& strText, - bool bSelect, - int imageId) +} // end of wxNotebook::DeleteAllPages + +// +// Add a page to the notebook +// +bool wxNotebook::AddPage ( + wxNotebookPage* pPage +, const wxString& rStrText +, bool bSelect +, int nImageId +) { - return InsertPage(GetPageCount(), pPage, strText, bSelect, imageId); -} - -// same as AddPage() but does it at given position -bool wxNotebook::InsertPage(int nPage, - wxNotebookPage *pPage, - const wxString& strText, - bool bSelect, - int imageId) + return InsertPage( GetPageCount() + ,pPage + ,rStrText + ,bSelect + ,nImageId + ); +} // end of wxNotebook::AddPage + +// +// Same as AddPage() but does it at given position +// +bool wxNotebook::InsertPage ( + int nPage +, wxNotebookPage* pPage +, const wxString& rsStrText +, bool bSelect +, int nImageId +) { + ULONG ulApiPage; + wxASSERT( pPage != NULL ); wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE ); - // TODO: insert native widget page - - // save the pointer to the page - m_aPages.Insert(pPage, nPage); + // + // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV. Requires + // two different calls to the API. Page 1 uses the BKA_FIRST. Subsequent + // pages use the previous page ID coupled with a BKA_NEXT call. Unlike + // Windows, OS/2 uses an internal Page ID to ID the pages. + // + // OS/2 also has a nice auto-size feature that automatically sizes the + // the attached window so we don't have to worry about the size of the + // window on the page. + // + if (nPage == 0) + { + ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND() + ,BKM_INSERTPAGE + ,(MPARAM)0 + ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST) + )); + if (ulApiPage == 0L) + { + ERRORID vError; + wxString sError; - // some page must be selected: either this one or the first one if there is - // still no selection - if ( bSelect ) - m_nSelection = nPage; - else if ( m_nSelection == -1 ) - m_nSelection = 0; + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + return FALSE; + } + m_alPageId.Insert((long)ulApiPage, nPage); + } + else + { + ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND() + ,BKM_INSERTPAGE + ,MPFROMLONG((ULONG)m_alPageId[nPage - 1]) + ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT) + )); + if (ulApiPage == 0L) + { + ERRORID vError; + wxString sError; - return TRUE; -} + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + return FALSE; + } + m_alPageId.Insert((long)ulApiPage, nPage); + } -// ---------------------------------------------------------------------------- -// wxNotebook callbacks -// ---------------------------------------------------------------------------- + // + // Associate a window handle with the page + // + if (pPage) + { + if (!::WinSendMsg( GetHWND() + ,BKM_SETPAGEWINDOWHWND + ,MPFROMLONG((ULONG)m_alPageId[nPage]) + ,MPFROMHWND(pPage->GetHWND()) + )) + return FALSE; + } + // + // If the inserted page is before the selected one, we must update the + // index of the selected page + // + if (nPage <= m_nSelection) + { + // + // One extra page added + // + m_nSelection++; + } -// @@@ OnSize() is used for setting the font when it's called for the first -// time because doing it in ::Create() doesn't work (for unknown reasons) -void wxNotebook::OnSize(wxSizeEvent& event) -{ - static bool s_bFirstTime = TRUE; - if ( s_bFirstTime ) { - // TODO: any first-time-size processing. - s_bFirstTime = FALSE; + if (pPage) + { + // + // Save the pointer to the page + // + m_pages.Insert( pPage + ,nPage + ); } - // TODO: all this may or may not be necessary for your platform + // + // Now set TAB dimenstions + // - // emulate page change (it's esp. important to do it first time because - // otherwise our page would stay invisible) - int nSel = m_nSelection; - m_nSelection = -1; - SetSelection(nSel); + wxWindowDC vDC(this); + wxCoord nTextX; + wxCoord nTextY; - // fit the notebook page to the tab control's display area - int w, h; - GetSize(&w, &h); + vDC.GetTextExtent(rsStrText, &nTextX, &nTextY); + nTextY *= 2; + nTextX *= 1.3; + if (nTextX > m_nTabSize) + { + m_nTabSize = nTextX; + ::WinSendMsg( GetHWND() + ,BKM_SETDIMENSIONS + ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY) + ,(MPARAM)BKA_MAJORTAB + ); + } + // + // Now set any TAB text + // + if (!rsStrText.IsEmpty()) + { + if (!SetPageText( nPage + ,rsStrText + )) + return FALSE; + } - unsigned int nCount = m_aPages.Count(); - for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) { - wxNotebookPage *pPage = m_aPages[nPage]; - pPage->SetSize(0, 0, w, h); -#if wxUSE_CONSTRAINTS - if ( pPage->GetAutoLayout() ) - pPage->Layout(); -#endif //wxUSE_CONSTRAINTS + // + // Now set any TAB bitmap image + // + if (nImageId != -1) + { + if (!SetPageImage( nPage + ,nImageId + )) + return FALSE; + } + if (pPage) + { + // + // Don't show pages by default (we'll need to adjust their size first) + // + HWND hWnd = GetWinHwnd(pPage); + + WinSetWindowULong( hWnd + ,QWL_STYLE + ,WinQueryWindowULong( hWnd + ,QWL_STYLE + ) & ~WS_VISIBLE + ); + + // + // This updates internal flag too - otherwise it will get out of sync + // + pPage->Show(FALSE); } - // Processing continues to next OnSize - event.Skip(); -} + // + // Some page should be selected: either this one or the first one if there is + // still no selection + // + int nSelNew = -1; + + if (bSelect) + nSelNew = nPage; + else if ( m_nSelection == -1 ) + nSelNew = 0; -void wxNotebook::OnSelChange(wxNotebookEvent& event) + if (nSelNew != -1) + SetSelection(nSelNew); + return TRUE; +} // end of wxNotebook::InsertPage + +// ---------------------------------------------------------------------------- +// wxNotebook callbacks +// ---------------------------------------------------------------------------- +void wxNotebook::OnSize( + wxSizeEvent& rEvent +) { - // is it our tab control? - if ( event.GetEventObject() == this ) + if (m_nSelection < m_pages.Count() && m_nSelection >= 0) + m_pages[m_nSelection]->Refresh(); + rEvent.Skip(); +} // end of wxNotebook::OnSize + +void wxNotebook::OnSelChange ( + wxNotebookEvent& rEvent +) +{ + // + // Is it our tab control? + // + if (rEvent.GetEventObject() == this) { - int sel = event.GetOldSelection(); - if ( sel != -1 ) - m_aPages[sel]->Show(FALSE); + int nSel = rEvent.GetOldSelection(); - sel = event.GetSelection(); - if ( sel != -1 ) + if (nSel != -1) + { + m_pages[nSel]->Show(FALSE); + m_pages[nSel]->SetActivePage(FALSE); + } + nSel = rEvent.GetSelection(); + if (nSel != -1) { - wxNotebookPage *pPage = m_aPages[sel]; + wxNotebookPage* pPage = m_pages[nSel]; + pPage->Show(TRUE); pPage->SetFocus(); + m_pages[nSel]->SetActivePage(TRUE); } + m_nSelection = nSel; + } - m_nSelection = sel; - } - // we want to give others a chance to process this message as well - event.Skip(); -} + // + // We want to give others a chance to process this message as well + // + rEvent.Skip(); +} // end of wxNotebook::OnSelChange -void wxNotebook::OnSetFocus(wxFocusEvent& event) +void wxNotebook::OnSetFocus ( + wxFocusEvent& rEvent +) { + // + // This function is only called when the focus is explicitly set (i.e. from + // the program) to the notebook - in this case we don't need the + // complicated OnNavigationKey() logic because the programmer knows better + // what [s]he wants + // // set focus to the currently selected page if any - if ( m_nSelection != -1 ) - m_aPages[m_nSelection]->SetFocus(); - - event.Skip(); -} - -void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event) + // + if (m_nSelection != -1) + m_pages[m_nSelection]->SetFocus(); + rEvent.Skip(); +} // end of wxNotebook::OnSetFocus + +void wxNotebook::OnNavigationKey ( + wxNavigationKeyEvent& rEvent +) { - if ( event.IsWindowChange() ) { - // change pages - AdvanceSelection(event.GetDirection()); + if (rEvent.IsWindowChange()) + { + // + // Change pages + // + AdvanceSelection(rEvent.GetDirection()); } - else { - // pass to the parent - if ( GetParent() ) { - event.SetCurrentFocus(this); - GetParent()->ProcessEvent(event); + else + { + // + // We get this event in 2 cases + // + // a) one of our pages might have generated it because the user TABbed + // out from it in which case we should propagate the event upwards and + // our parent will take care of setting the focus to prev/next sibling + // + // or + // + // b) the parent panel wants to give the focus to us so that we + // forward it to our selected page. We can't deal with this in + // OnSetFocus() because we don't know which direction the focus came + // from in this case and so can't choose between setting the focus to + // first or last panel child + // + wxWindow* pParent = GetParent(); + + if (rEvent.GetEventObject() == pParent) + { + // + // No, it doesn't come from child, case (b): forward to a page + // + if (m_nSelection != -1) + { + // + // So that the page knows that the event comes from it's parent + // and is being propagated downwards + // + rEvent.SetEventObject(this); + + wxWindow* pPage = m_pages[m_nSelection]; + + if (!pPage->GetEventHandler()->ProcessEvent(rEvent)) + { + pPage->SetFocus(); + } + //else: page manages focus inside it itself + } + else + { + // + // We have no pages - still have to give focus to _something_ + // + SetFocus(); + } + } + else + { + // + // It comes from our child, case (a), pass to the parent + // + if (pParent) + { + rEvent.SetCurrentFocus(this); + pParent->GetEventHandler()->ProcessEvent(rEvent); + } } } -} +} // end of wxNotebook::OnNavigationKey // ---------------------------------------------------------------------------- // wxNotebook base class virtuals // ---------------------------------------------------------------------------- -// override these 2 functions to do nothing: everything is done in OnSize - -void wxNotebook::SetConstraintSizes(bool /* recurse */) +// +// Override these 2 functions to do nothing: everything is done in OnSize +// +void wxNotebook::SetConstraintSizes( + bool WXUNUSED(bRecurse) +) { -#if wxUSE_CONSTRAINTS - // don't set the sizes of the pages - their correct size is not yet known + // + // Don't set the sizes of the pages - their correct size is not yet known + // wxControl::SetConstraintSizes(FALSE); -#endif -} +} // end of wxNotebook::SetConstraintSizes -bool wxNotebook::DoPhase(int /* nPhase */) +bool wxNotebook::DoPhase ( + int WXUNUSED(nPhase) +) { return TRUE; -} +} // end of wxNotebook::DoPhase -bool wxNotebook::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result) +// ---------------------------------------------------------------------------- +// wxNotebook Windows message handlers +// ---------------------------------------------------------------------------- +bool wxNotebook::OS2OnScroll ( + int nOrientation +, WXWORD wSBCode +, WXWORD wPos +, WXHWND wControl +) { - wxNotebookEvent event(wxEVT_NULL, m_windowId); -//TODO: -/* - NMHDR* hdr = (NMHDR *)lParam; - switch ( hdr->code ) { - case TCN_SELCHANGE: - event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED); - break; - - case TCN_SELCHANGING: - event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING); - break; - - default: - return wxControl::MSWOnNotify(idCtrl, lParam, result); - } -*/ -// TODO: event.SetSelection(TabCtrl_GetCurSel(m_hwnd)); - event.SetOldSelection(m_nSelection); - event.SetEventObject(this); - event.SetInt(idCtrl); - - bool processed = GetEventHandler()->ProcessEvent(event); -// TODO: *result = !event.IsAllowed(); - return processed; -} + // + // Don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the + // up-down control + // + if (wControl) + return FALSE; + return wxNotebookBase::OS2OnScroll( nOrientation + ,wSBCode + ,wPos + ,wControl + ); +} // end of wxNotebook::OS2OnScroll // ---------------------------------------------------------------------------- // wxNotebook helper functions // ---------------------------------------------------------------------------- -// hide the currently active panel and show the new one -void wxNotebook::ChangePage(int nOldSel, int nSel) +// +// Generate the page changing and changed events, hide the currently active +// panel and show the new one +// +void wxNotebook::ChangePage ( + int nOldSel +, int nSel +) { - // MT-FIXME should use a real semaphore - static bool s_bInsideChangePage = FALSE; + static bool sbInsideChangePage = FALSE; - // when we call ProcessEvent(), our own OnSelChange() is called which calls + // + // When we call ProcessEvent(), our own OnSelChange() is called which calls // this function - break the infinite loop - if ( s_bInsideChangePage ) + // + if (sbInsideChangePage) return; - // it's not an error (the message may be generated by the tab control itself) + // + // It's not an error (the message may be generated by the tab control itself) // and it may happen - just do nothing - if ( nSel == nOldSel ) + // + if (nSel == nOldSel) return; - s_bInsideChangePage = TRUE; + sbInsideChangePage = TRUE; + + wxNotebookEvent rEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING + ,m_windowId + ); - wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId); - event.SetSelection(nSel); - event.SetOldSelection(nOldSel); - event.SetEventObject(this); - if ( ProcessEvent(event) && !event.IsAllowed() ) + rEvent.SetSelection(nSel); + rEvent.SetOldSelection(nOldSel); + rEvent.SetEventObject(this); + if (GetEventHandler()->ProcessEvent(rEvent) && !rEvent.IsAllowed()) { - // program doesn't allow the page change - s_bInsideChangePage = FALSE; + // + // Program doesn't allow the page change + // + sbInsideChangePage = FALSE; return; } + rEvent.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED); + GetEventHandler()->ProcessEvent(rEvent); + sbInsideChangePage = FALSE; +} // end of wxNotebook::ChangePage - event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED); - ProcessEvent(event); - - s_bInsideChangePage = FALSE; -} +#endif // wxUSE_NOTEBOOK diff --git a/src/os2/radiobox.cpp b/src/os2/radiobox.cpp index 8a11e966c4..01871f8e90 100644 --- a/src/os2/radiobox.cpp +++ b/src/os2/radiobox.cpp @@ -36,13 +36,22 @@ MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd ,MPARAM wParam ,MPARAM lParam ); +MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd + ,UINT uMessage + ,MPARAM wParam + ,MPARAM lParam + ); // --------------------------------------------------------------------------- // global vars // --------------------------------------------------------------------------- // the pointer to standard radio button wnd proc +extern void wxAssociateWinWithHandle( HWND hWnd + ,wxWindowOS2* pWin + ); static WXFARPROC fnWndProcRadioBtn = NULL; +static WXFARPROC fnWndProcRadioBox = NULL; // =========================================================================== // implementation @@ -260,20 +269,10 @@ bool wxRadioBox::Create( , const wxString& rsName ) { - // - // System fonts are too big in OS/2 and they are blue - // We want smaller fonts and black by default. - // - wxFont* pTextFont = new wxFont( 10 - ,wxMODERN - ,wxNORMAL - ,wxNORMAL - ); wxColour vColour; LONG lColor; vColour.Set(wxString("BLACK")); - lColor = (LONG)vColour.GetPixel(); m_backgroundColour = pParent->GetBackgroundColour(); m_nSelectedButton = -1; m_nNoItems = 0; @@ -296,17 +295,14 @@ bool wxRadioBox::Create( )) return FALSE; if (!OS2CreateControl( "STATIC" -#if RADIOBTN_PARENT_IS_RADIOBOX - ,SS_GROUPBOX | WS_GROUP | WS_CLIPCHILDREN -#else - ,SS_GROUPBOX | WS_GROUP | WS_CLIPSIBLINGS -#endif + ,SS_GROUPBOX ,rPos ,rSize ,rsTitle )) return FALSE; + wxAssociateWinWithHandle(m_hWnd, this); #if RADIOBTN_PARENT_IS_RADIOBOX HWND hWndParent = GetHwnd(); #else @@ -323,11 +319,6 @@ bool wxRadioBox::Create( m_pnRadioWidth = new int[nNum]; m_pnRadioHeight = new int[nNum]; - if (pTextFont->Ok()) - { - hFont = pTextFont->GetResourceHandle(); - } - for (int i = 0; i < nNum; i++) { m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1; @@ -368,8 +359,9 @@ bool wxRadioBox::Create( } m_ahRadioButtons[i] = (WXHWND)hWndBtn; SubclassRadioButton((WXHWND)hWndBtn); + wxAssociateWinWithHandle(hWndBtn, this); wxOS2SetFont( hWndBtn - ,*pTextFont + ,*wxSMALL_FONT ); ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this); m_aSubControls.Add(nNewId); @@ -389,13 +381,22 @@ bool wxRadioBox::Create( ,NULL ,NULL ); - SetFont(*pTextFont); + SetFont(*wxSMALL_FONT); + fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd() + ,(PFNWP)wxRadioBoxWndProc + ); + ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this); lColor = (LONG)vColour.GetPixel(); ::WinSetPresParam( m_hWnd ,PP_FOREGROUNDCOLOR ,sizeof(LONG) ,(PVOID)&lColor ); + ::WinSetPresParam( m_hWnd + ,PP_BORDERDARKCOLOR + ,sizeof(LONG) + ,(PVOID)&lColor + ); lColor = (LONG)m_backgroundColour.GetPixel(); ::WinSetPresParam( m_hWnd @@ -403,6 +404,11 @@ bool wxRadioBox::Create( ,sizeof(LONG) ,(PVOID)&lColor ); + ::WinSetPresParam( m_hWnd + ,PP_BORDERLIGHTCOLOR + ,sizeof(LONG) + ,(PVOID)&lColor + ); SetXComp(0); SetYComp(0); SetSelection(0); @@ -411,7 +417,6 @@ bool wxRadioBox::Create( ,rSize.x ,rSize.y ); - delete pTextFont; return TRUE; } // end of wxRadioBox::Create @@ -969,10 +974,8 @@ bool wxRadioBox::OS2Command( if (nSelectedButton == -1) { // - // Just ignore it - due to a hack with WM_NCHITTEST handling in our - // wnd proc, we can receive dummy click messages when we click near - // the radiobox edge (this is ugly but Julian wouldn't let me get - // rid of this...) + // Just ignore it + // return FALSE; } if (nSelectedButton != m_nSelectedButton) @@ -1213,3 +1216,18 @@ MRESULT wxRadioBtnWndProc( ); } // end of wxRadioBtnWndProc +MRESULT EXPENTRY wxRadioBoxWndProc( + HWND hWnd +, UINT uMessage +, MPARAM wParam +, MPARAM lParam +) +{ + return (fnWndProcRadioBox( hWnd + ,(ULONG)uMessage + ,(MPARAM)wParam + ,(MPARAM)lParam + ) + ); +} // end of wxRadioBoxWndProc + diff --git a/src/os2/radiobut.cpp b/src/os2/radiobut.cpp index d4cc561bab..0b8784621c 100644 --- a/src/os2/radiobut.cpp +++ b/src/os2/radiobut.cpp @@ -29,6 +29,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl) +extern void wxAssociateWinWithHandle( HWND hWnd + ,wxWindowOS2* pWin + ); + void wxRadioButton::Init() { m_bFocusJustSet = FALSE; @@ -82,21 +86,16 @@ bool wxRadioButton::Create( )) return FALSE; + wxAssociateWinWithHandle(m_hWnd, this); if (HasFlag(wxRB_GROUP)) SetValue(TRUE); - wxFont* pTextFont = new wxFont( 10 - ,wxMODERN - ,wxNORMAL - ,wxNORMAL - ); - SetFont(*pTextFont); + SetFont(*wxSMALL_FONT); SetSize( rPos.x ,rPos.y ,rSize.x ,rSize.y ); - delete pTextFont; return TRUE; } // end of wxRadioButton::Create diff --git a/src/os2/window.cpp b/src/os2/window.cpp index 85f6f74323..7e0ac7cb4e 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -301,6 +301,7 @@ void wxWindowOS2::Init() m_bUseCtl3D = FALSE; m_bMouseInWindow = FALSE; m_bLastKeydownProcessed = FALSE; + m_bIsActivePage = TRUE; // // wxWnd @@ -1646,13 +1647,86 @@ void wxWindowOS2::DoMoveWindow( ::WinQueryWindowRect(HWND_DESKTOP, &vRect); nY = vRect.yTop - (nY + nHeight); } + + // + // In the case of a frame whose client is sized, the client cannot be + // large than its parent frame minus its borders! This usually happens + // when using an autosizer to size a frame to precisely hold client + // controls as in the notebook sample. + // + // In this case, we may need to resize both a frame and its client so we + // need a quick calc of the frame border size, then if the frame + // (less its borders) is smaller than the client, size the frame to + // encompass the client with the appropriate border size. + // + if (IsKindOf(CLASSINFO(wxFrame))) + { + RECTL vFRect; + HWND hWndFrame; + int nWidthFrameDelta = 0; + int nHeightFrameDelta = 0; + int nHeightFrame = 0; + int nWidthFrame = 0; + ULONG ulFLag = SWP_MOVE; + wxFrame* pFrame; + + pFrame = wxDynamicCast(this, wxFrame); + hWndFrame = pFrame->GetFrame(); + ::WinQueryWindowRect(hWndFrame, &vRect); + ::WinMapWindowPoints(hWndFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2); + vFRect = vRect; + ::WinCalcFrameRect(hWndFrame, &vRect, TRUE); + nWidthFrameDelta = ((vRect.xLeft - vFRect.xLeft) + (vFRect.xRight - vRect.xRight)); + nHeightFrameDelta = ((vRect.yBottom - vFRect.yBottom) + (vFRect.yTop - vRect.yTop)); + nWidthFrame = vFRect.xRight - vFRect.xLeft; + nHeightFrame = vFRect.yTop - vFRect.yBottom; + + if (nWidth == vFRect.xRight - vFRect.xLeft && + nHeight == vFRect.yTop - vFRect.yBottom) + { + // + // In this case the caller is not aware of OS/2's need to size both + // the frame and it's client and is really only moving the window, + // not resizeing it. So move the frame, and back off the sizes + // for a proper client fit. + // + ::WinSetWindowPos( hWndFrame + ,HWND_TOP + ,(LONG)nX - (vRect.xLeft - vFRect.xLeft) + ,(LONG)nY - (vRect.yBottom - vFRect.yBottom) + ,(LONG)0 + ,(LONG)0 + ,SWP_MOVE + ); + nX += (vRect.xLeft - vFRect.xLeft); + nY += (vRect.yBottom - vFRect.yBottom); + nWidth -= nWidthFrameDelta; + nHeight -= nHeightFrameDelta; + } + else + { + if (nWidth > nWidthFrame - nHeightFrameDelta || + nHeight > nHeightFrame - nHeightFrameDelta) + { + ::WinSetWindowPos( hWndFrame + ,HWND_TOP + ,(LONG)nX - (vRect.xLeft - vFRect.xLeft) + ,(LONG)nY - (vRect.yBottom - vFRect.yBottom) + ,(LONG)nWidth + nWidthFrameDelta + ,(LONG)nHeight + nHeightFrameDelta + ,SWP_MOVE | SWP_SIZE + ); + } + } + } + ::WinSetWindowPos( GetHwnd() ,HWND_TOP ,(LONG)nX ,(LONG)nY ,(LONG)nWidth ,(LONG)nHeight - ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW + ,SWP_SIZE | SWP_MOVE ); if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0) // @@ -2853,6 +2927,48 @@ MRESULT wxWindowOS2::OS2WindowProc( case WM_CONTROL: switch(SHORT2FROMMP(wParam)) { + case BN_CLICKED: + { + HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam)); + wxWindowOS2* pWin = wxFindWinFromHandle(hWnd); + + if (!pWin) + { + bProcessed = FALSE; + break; + } + // + // Simulate a WM_COMMAND here, as wxWindows expects all control + // button clicks to generate WM_COMMAND msgs, not WM_CONTROL + // + if (pWin->IsKindOf(CLASSINFO(wxRadioBox))) + { + wxRadioBox* pRadioBox = wxDynamicCast(pWin, wxRadioBox); + + pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam) + ,(WXUINT)SHORT1FROMMP(wParam) + ); + } + if (pWin->IsKindOf(CLASSINFO(wxRadioButton))) + { + wxRadioButton* pRadioButton = wxDynamicCast(pWin, wxRadioButton); + + pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam) + ,(WXUINT)SHORT1FROMMP(wParam) + ); + } + if (pWin->IsKindOf(CLASSINFO(wxCheckBox))) + { + wxCheckBox* pCheckBox = wxDynamicCast(pWin, wxCheckBox); + + pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam) + ,(WXUINT)SHORT1FROMMP(wParam) + ); + } + return 0; + } + break; + case SPBN_UPARROW: case SPBN_DOWNARROW: case SPBN_CHANGE: @@ -3322,7 +3438,7 @@ bool wxWindowOS2::HandleKillFocus( #endif // wxUSE_CARET #if wxUSE_TEXTCTRL - // + // // If it's a wxTextCtrl don't send the event as it will be done // after the control gets to process it. // @@ -3334,7 +3450,7 @@ bool wxWindowOS2::HandleKillFocus( } #endif - // + // // Don't send the event when in the process of being deleted. This can // only cause problems if the event handler tries to access the object. // @@ -3349,7 +3465,7 @@ bool wxWindowOS2::HandleKillFocus( vEvent.SetEventObject(this); - // + // // wxFindWinFromHandle() may return NULL, it is ok // vEvent.SetWindow(wxFindWinFromHandle(hWnd)); @@ -3718,7 +3834,9 @@ bool wxWindowOS2::HandlePaint() { // // OS/2 needs to process this right here, not by the default proc - // Window's default proc correctly paints everything, OS/2 does not! + // Window's default proc correctly paints everything, OS/2 does not. + // For decorative panels that typically have no children, we draw + // borders. // HPS hPS; RECTL vRect; @@ -3746,35 +3864,76 @@ bool wxWindowOS2::HandlePaint() ,NULL ); - ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel()); - if (m_dwExStyle) + if (::WinIsWindowVisible(GetHWND()) && m_bIsActivePage) { - LINEBUNDLE vLineBundle; - - vLineBundle.lColor = 0x00000000; // Black - vLineBundle.usMixMode = FM_OVERPAINT; - vLineBundle.fxWidth = 1; - vLineBundle.lGeomWidth = 1; - vLineBundle.usType = LINETYPE_SOLID; - vLineBundle.usEnd = 0; - vLineBundle.usJoin = 0; - ::GpiSetAttrs( hPS - ,PRIM_LINE - ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE - ,0L - ,&vLineBundle - ); - ::WinQueryWindowRect(GetHwnd(), &vRect); - wxDrawBorder( hPS - ,vRect - ,m_dwExStyle - ); + ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel()); + if (m_dwExStyle) + { + LINEBUNDLE vLineBundle; + + vLineBundle.lColor = 0x00000000; // Black + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 1; + vLineBundle.lGeomWidth = 1; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + ::WinQueryWindowRect(GetHwnd(), &vRect); + wxDrawBorder( hPS + ,vRect + ,m_dwExStyle + ); + } } - ::WinEndPaint(hPS); } + ::WinEndPaint(hPS); bProcessed = TRUE; } + else if (!bProcessed && + IsKindOf(CLASSINFO(wxPanel)) + ) + { + // + // Panel with children, usually fills a frame client so no borders. + // + HPS hPS; + RECTL vRect; + wxFrame* pFrame; + wxWindow* pParent; + hPS = ::WinBeginPaint( GetHwnd() + ,NULLHANDLE + ,&vRect + ); + if(hPS) + { + ::GpiCreateLogColorTable( hPS + ,0L + ,LCOLF_CONSECRGB + ,0L + ,(LONG)wxTheColourDatabase->m_nSize + ,(PLONG)wxTheColourDatabase->m_palTable + ); + ::GpiCreateLogColorTable( hPS + ,0L + ,LCOLF_RGB + ,0L + ,0L + ,NULL + ); + + if (::WinIsWindowVisible(GetHWND()) && m_bIsActivePage) + ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel()); + } + ::WinEndPaint(hPS); + bProcessed = TRUE; + } return bProcessed; } // end of wxWindowOS2::HandlePaint @@ -4300,62 +4459,69 @@ void wxWindowOS2::MoveChildren( int nDiff ) { - SWP vSwp; - - for (wxWindowList::Node* pNode = GetChildren().GetFirst(); - pNode; - pNode = pNode->GetNext()) + if (GetAutoLayout()) { - wxWindow* pWin = pNode->GetData(); + Layout(); + } + else + { + SWP vSwp; - ::WinQueryWindowPos( GetHwndOf(pWin) - ,&vSwp - ); - if (pWin->IsKindOf(CLASSINFO(wxControl))) + for (wxWindowList::Node* pNode = GetChildren().GetFirst(); + pNode; + pNode = pNode->GetNext()) { - wxControl* pCtrl; + wxWindow* pWin = pNode->GetData(); - // - // Must deal with controls that have margins like ENTRYFIELD. The SWP - // struct of such a control will have and origin offset from its intended - // position by the width of the margins. - // - pCtrl = wxDynamicCast(pWin, wxControl); - vSwp.y -= pCtrl->GetYComp(); - vSwp.x -= pCtrl->GetXComp(); - } - ::WinSetWindowPos( GetHwndOf(pWin) - ,HWND_TOP - ,vSwp.x - ,vSwp.y - nDiff - ,vSwp.cx - ,vSwp.cy - ,SWP_MOVE | SWP_SHOW | SWP_ZORDER - ); - ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp()); - if (pWin->IsKindOf(CLASSINFO(wxRadioBox))) - { - wxRadioBox* pRadioBox; - - pRadioBox = wxDynamicCast(pWin, wxRadioBox); - pRadioBox->AdjustButtons( (int)vSwp.x - ,(int)vSwp.y - nDiff - ,(int)vSwp.cx - ,(int)vSwp.cy - ,pRadioBox->GetSizeFlags() - ); - } - if (pWin->IsKindOf(CLASSINFO(wxSlider))) - { - wxSlider* pSlider; - - pSlider = wxDynamicCast(pWin, wxSlider); - pSlider->AdjustSubControls( (int)vSwp.x - ,(int)vSwp.y - nDiff - ,(int)vSwp.cx - ,(int)vSwp.cy - ,(int)pSlider->GetSizeFlags() - ); + ::WinQueryWindowPos( GetHwndOf(pWin) + ,&vSwp + ); + if (pWin->IsKindOf(CLASSINFO(wxControl))) + { + wxControl* pCtrl; + + // + // Must deal with controls that have margins like ENTRYFIELD. The SWP + // struct of such a control will have and origin offset from its intended + // position by the width of the margins. + // + pCtrl = wxDynamicCast(pWin, wxControl); + vSwp.y -= pCtrl->GetYComp(); + vSwp.x -= pCtrl->GetXComp(); + } + ::WinSetWindowPos( GetHwndOf(pWin) + ,HWND_TOP + ,vSwp.x + ,vSwp.y - nDiff + ,vSwp.cx + ,vSwp.cy + ,SWP_MOVE | SWP_SHOW | SWP_ZORDER + ); + ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp()); + if (pWin->IsKindOf(CLASSINFO(wxRadioBox))) + { + wxRadioBox* pRadioBox; + + pRadioBox = wxDynamicCast(pWin, wxRadioBox); + pRadioBox->AdjustButtons( (int)vSwp.x + ,(int)vSwp.y - nDiff + ,(int)vSwp.cx + ,(int)vSwp.cy + ,pRadioBox->GetSizeFlags() + ); + } + if (pWin->IsKindOf(CLASSINFO(wxSlider))) + { + wxSlider* pSlider; + + pSlider = wxDynamicCast(pWin, wxSlider); + pSlider->AdjustSubControls( (int)vSwp.x + ,(int)vSwp.y - nDiff + ,(int)vSwp.cx + ,(int)vSwp.cy + ,(int)pSlider->GetSizeFlags() + ); + } } } Refresh(); diff --git a/src/os2/wx23.def b/src/os2/wx23.def index ad99183d6d..4c8cebe451 100644 --- a/src/os2/wx23.def +++ b/src/os2/wx23.def @@ -4,7 +4,7 @@ DATA MULTIPLE NONSHARED READWRITE LOADONCALL CODE LOADONCALL EXPORTS -;From library: H:\DEV\WX2\WXWINDOWS\lib\wx.lib +;From library: H:\Dev\Wx2\WxWindows\lib\wx.lib ;From object file: dummy.cpp ;PUBDEFs (Symbols available from object file): wxDummyChar @@ -13638,8 +13638,6 @@ EXPORTS DeleteAllPages__10wxNotebookFv ;wxNotebook::SetPageText(int,const wxString&) SetPageText__10wxNotebookFiRC8wxString - ;wxNotebook::AdvanceSelection(unsigned long) - AdvanceSelection__10wxNotebookFUl wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED ;wxNotebook::ChangePage(int,int) ChangePage__10wxNotebookFiT1 @@ -13649,6 +13647,8 @@ EXPORTS SetPageSize__10wxNotebookFRC6wxSize ;wxNotebook::AddPage(wxWindow*,const wxString&,unsigned long,int) AddPage__10wxNotebookFP8wxWindowRC8wxStringUli + ;wxNotebook::OS2GetStyle(long,unsigned long*) const + OS2GetStyle__10wxNotebookCFlPUl ;wxNotebook::OnSize(wxSizeEvent&) OnSize__10wxNotebookFR11wxSizeEvent ;wxNotebook::SetSelection(int) @@ -13657,8 +13657,6 @@ EXPORTS SetPageImage__10wxNotebookFiT1 ;wxNotebook::DoPhase(int) DoPhase__10wxNotebookFi - ;wxNotebook::DeletePage(int) - DeletePage__10wxNotebookFi ;wxNotebook::GetPageCount() const GetPageCount__10wxNotebookCFv ;wxNotebook::wxNotebook(wxWindow*,int,const wxPoint&,const wxSize&,long,const wxString&) @@ -13679,8 +13677,6 @@ EXPORTS wxConstructorForwxNotebook__Fv ;wxConstructorForwxNotebookEvent() wxConstructorForwxNotebookEvent__Fv - ;wxNotebook::OS2OnNotify(int,void*,void**) - OS2OnNotify__10wxNotebookFiPvPPv ;wxNotebook::Init() Init__10wxNotebookFv ;wxNotebook::sm_classwxNotebook @@ -13688,17 +13684,17 @@ EXPORTS wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING ;wxNotebook::sm_eventTable sm_eventTable__10wxNotebook + ;wxNotebook::OS2OnScroll(int,unsigned short,unsigned short,unsigned long) + OS2OnScroll__10wxNotebookFiUsT2Ul __vft10wxNotebook8wxObject ;wxNotebook::GetPageImage(int) const GetPageImage__10wxNotebookCFi - ;wxNotebook::RemovePage(int) - RemovePage__10wxNotebookFi ;wxNotebook::InsertPage(int,wxWindow*,const wxString&,unsigned long,int) InsertPage__10wxNotebookFiP8wxWindowRC8wxStringUlT1 + ;wxNotebook::DoRemovePage(int) + DoRemovePage__10wxNotebookFi ;wxNotebook::GetEventTable() const GetEventTable__10wxNotebookCFv - ;wxNotebook::~wxNotebook() - __dt__10wxNotebookFv ;wxNotebook::GetRowCount() const GetRowCount__10wxNotebookCFv ;wxNotebook::Create(wxWindow*,int,const wxPoint&,const wxSize&,long,const wxString&) @@ -13890,6 +13886,7 @@ EXPORTS GetRowCount__10wxRadioBoxCFv ;wxRadioBox::Create(wxWindow*,int,const wxString&,const wxPoint&,const wxSize&,int,const wxString*,int,long,const wxValidator&,const wxString&) Create__10wxRadioBoxFP8wxWindowiRC8wxStringRC7wxPointRC6wxSizeT2PC8wxStringT2lRC11wxValidatorT3 + wxRadioBoxWndProc ;wxRadioBox::FindString(const wxString&) const FindString__10wxRadioBoxCFRC8wxString __vft10wxRadioBox8wxObject