diff --git a/include/wx/event.h b/include/wx/event.h index 0453f4fc9a..8b24b15256 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -720,12 +720,33 @@ public: wxEVT_PAINT_ICON */ +#if defined(__WXDEBUG__) && defined(__WXMSW__) + // see comments in src/msw/dcclient.cpp where g_isPainting is defined + extern int g_isPainting; +#endif // debug + class WXDLLEXPORT wxPaintEvent : public wxEvent { DECLARE_DYNAMIC_CLASS(wxPaintEvent) public: - wxPaintEvent(int Id = 0) { m_eventType = wxEVT_PAINT; m_id = Id; } + wxPaintEvent(int Id = 0) + { + m_eventType = wxEVT_PAINT; + m_id = Id; + +#if defined(__WXDEBUG__) && defined(__WXMSW__) + // set the internal flag for the duration of processing of WM_PAINT + g_isPainting++; +#endif // debug + } + +#if defined(__WXDEBUG__) && defined(__WXMSW__) + ~wxPaintEvent() + { + g_isPainting--; + } +#endif // debug }; // Erase background event class diff --git a/include/wx/generic/panelg.h b/include/wx/generic/panelg.h index a4c8029462..ffde79e48e 100644 --- a/include/wx/generic/panelg.h +++ b/include/wx/generic/panelg.h @@ -24,7 +24,7 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr; class WXDLLEXPORT wxPanel : public wxWindow { public: - wxPanel(); + wxPanel() { Init(); } // Old-style constructor (no default values for coordinates to avoid // ambiguity with the new one) @@ -33,6 +33,8 @@ public: long style = wxTAB_TRAVERSAL | wxNO_BORDER, const wxString& name = wxPanelNameStr) { + Init(); + Create(parent, -1, wxPoint(x, y), wxSize(width, height), style, name); } @@ -58,7 +60,13 @@ public: // to the dialog via validators. virtual void InitDialog(); - // implementation + // a default button is activated when Enter is pressed + wxButton *GetDefaultItem() const { return m_btnDefault; } + void SetDefaultItem(wxButton *btn) { m_btnDefault = btn; } + + // implementation from now on + // -------------------------- + // responds to colour changes void OnSysColourChanged(wxSysColourChangedEvent& event); @@ -73,9 +81,15 @@ public: long GetLastFocus() const { return m_lastFocus; } protected: + // common part of all ctors + void Init(); + // the child which had the focus last time this panel was activated long m_lastFocus; + // a default button or NULL + wxButton *m_btnDefault; + private: DECLARE_DYNAMIC_CLASS(wxPanel) DECLARE_EVENT_TABLE() diff --git a/include/wx/msw/button.h b/include/wx/msw/button.h index d4e85575e9..cd0e1df385 100644 --- a/include/wx/msw/button.h +++ b/include/wx/msw/button.h @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_BUTTON_H_ @@ -17,11 +17,13 @@ #endif #include "wx/control.h" -#include "wx/gdicmn.h" WXDLLEXPORT_DATA(extern const wxChar*) wxButtonNameStr; +// ---------------------------------------------------------------------------- // Pushbutton +// ---------------------------------------------------------------------------- + class WXDLLEXPORT wxButton : public wxControl { DECLARE_DYNAMIC_CLASS(wxButton) @@ -43,15 +45,24 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxButtonNameStr); + virtual ~wxButton(); + virtual void SetDefault(); - virtual void SetLabel(const wxString& label); - virtual wxString GetLabel() const ; + + // implementation from now on virtual void Command(wxCommandEvent& event); virtual bool MSWCommand(WXUINT param, WXWORD id); - virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, - WXUINT message, WXWPARAM wParam, WXLPARAM lParam); + virtual WXHBRUSH OnCtlColor(WXHDC pDC, + WXHWND pWnd, + WXUINT nCtlColor, + WXUINT message, + WXWPARAM wParam, + WXLPARAM lParam); protected: + // send a notification event, return TRUE if processed + bool SendClickEvent(); + virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index 0b1eecff65..e6fe84f0cf 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -69,8 +69,6 @@ - in Win95, you can be called back to supply other information besides text, such as state information. This saves no memory and is probably superfluous to requirements. - - discover why SetWindowLong doesn't properly change the - style, requiring RecreateWindow instead. - testing of whole API, extending current sample. @@ -411,8 +409,8 @@ class WXDLLEXPORT wxListCtrl: public wxControl virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); - // Recreate window - seems to be necessary when changing a style. - void RecreateWindow(); + // bring the control in sync with current m_windowStyle value + void UpdateStyle(); // Add to pool: necessary because Windows needs to have a string // still exist across 3 callbacks. @@ -430,6 +428,8 @@ protected: int m_colCount; // Windows doesn't have GetColumnCount so must // keep track of inserted/deleted columns +private: + bool DoCreateControl(int x, int y, int w, int h); }; class WXDLLEXPORT wxListEvent : public wxNotifyEvent diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index c218411d05..6ee8daab71 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -181,11 +181,6 @@ public: void OnEraseBackground(wxEraseEvent& event); void OnIdle(wxIdleEvent& event); - // a window may have a default button - // TODO move into wxPanel and/or wxFrame - wxButton *GetDefaultItem() const { return m_btnDefault; } - void SetDefaultItem(wxButton *btn) { m_btnDefault = btn; } - public: // For implementation purposes - sometimes decorations make the client area // smaller diff --git a/src/common/image.cpp b/src/common/image.cpp index 91fc0fb9be..153472c88d 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -15,7 +15,7 @@ #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #include "wx/image.h" @@ -32,13 +32,11 @@ #include #ifdef __SALFORDC__ -#ifdef FAR -#undef FAR -#endif + #undef FAR #endif #ifdef __WXMSW__ -#include + #include "wx/msw/private.h" #endif //----------------------------------------------------------------------------- @@ -49,8 +47,8 @@ class wxImageRefData: public wxObjectRefData { public: - wxImageRefData(void); - ~wxImageRefData(void); + wxImageRefData(); + ~wxImageRefData(); int m_width; int m_height; @@ -60,7 +58,7 @@ public: bool m_ok; }; -wxImageRefData::wxImageRefData(void) +wxImageRefData::wxImageRefData() { m_width = 0; m_height = 0; @@ -72,7 +70,7 @@ wxImageRefData::wxImageRefData(void) m_hasMask = FALSE; } -wxImageRefData::~wxImageRefData(void) +wxImageRefData::~wxImageRefData() { if (m_data) free( m_data ); } @@ -84,7 +82,7 @@ wxList wxImage::sm_handlers; #define M_IMGDATA ((wxImageRefData *)m_refData) #if !USE_SHARED_LIBRARIES -IMPLEMENT_DYNAMIC_CLASS(wxImage, wxObject) + IMPLEMENT_DYNAMIC_CLASS(wxImage, wxObject) #endif wxImage::wxImage() diff --git a/src/generic/panelg.cpp b/src/generic/panelg.cpp index 2b74c65445..9ae2865482 100644 --- a/src/generic/panelg.cpp +++ b/src/generic/panelg.cpp @@ -40,9 +40,10 @@ END_EVENT_TABLE() #endif -wxPanel::wxPanel() +void wxPanel::Init() { m_lastFocus = 0; + m_btnDefault = (wxButton *)NULL; } bool wxPanel::Create(wxWindow *parent, wxWindowID id, @@ -51,8 +52,6 @@ bool wxPanel::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { - m_lastFocus = 0; - bool ret = wxWindow::Create(parent, id, pos, size, style, name); if ( ret ) diff --git a/src/msw/app.cpp b/src/msw/app.cpp index 944714414d..caf8b6e696 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -86,7 +86,6 @@ #include "wx/msw/msvcrt.h" - // --------------------------------------------------------------------------- // global variables // --------------------------------------------------------------------------- diff --git a/src/msw/button.cpp b/src/msw/button.cpp index aff5ee1b47..4a5a7bbf4e 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -6,195 +6,218 @@ // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- #ifdef __GNUG__ -#pragma implementation "button.h" + #pragma implementation "button.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #ifndef WX_PRECOMP -#include "wx/button.h" -#include "wx/brush.h" + #include "wx/button.h" + #include "wx/brush.h" #endif #include "wx/msw/private.h" +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + #if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) + IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) #endif +// this macro tries to adjust the default button height to a reasonable value +// using the char height as the base #define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10) -// Buttons +// ============================================================================ +// implementation +// ============================================================================ -bool wxButton::MSWCommand(WXUINT param, WXWORD id) +// ---------------------------------------------------------------------------- +// creation/destruction +// ---------------------------------------------------------------------------- + +bool wxButton::Create(wxWindow *parent, + wxWindowID id, + const wxString& label, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& validator, + const wxString& name) { - if (param == BN_CLICKED || (param == 1)) // 1 for accelerator - { - wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, id); - event.SetEventObject(this); - ProcessCommand(event); + if ( !CreateBase(parent, id, pos, size, style, name) ) + return FALSE; + + SetValidator(validator); + + parent->AddChild((wxButton *)this); + + m_backgroundColour = parent->GetBackgroundColour() ; + m_foregroundColour = parent->GetForegroundColour() ; + + m_hWnd = (WXHWND)CreateWindowEx + ( + MakeExtendedStyle(m_windowStyle), + _T("BUTTON"), + label, + WS_VISIBLE | WS_TABSTOP | WS_CHILD, + 0, 0, 0, 0, + GetWinHwnd(parent), + (HMENU)m_windowId, + wxGetInstance(), + NULL + ); + + // Subclass again for purposes of dialog editing mode + SubclassWin(m_hWnd); + + SetFont(parent->GetFont()); + + SetSize(pos.x, pos.y, size.x, size.y); + return TRUE; - } - else return FALSE; } -bool wxButton::Create(wxWindow *parent, wxWindowID id, const wxString& label, - const wxPoint& pos, - const wxSize& size, long style, - const wxValidator& validator, - const wxString& name) +wxButton::~wxButton() { - SetName(name); - SetValidator(validator); - - parent->AddChild((wxButton *)this); - m_backgroundColour = parent->GetBackgroundColour() ; - m_foregroundColour = parent->GetForegroundColour() ; - - m_windowStyle = (long&)style; - - int x = pos.x; - int y = pos.y; - int width = size.x; - int height = size.y; - - if (id == -1) - m_windowId = NewControlId(); - else - m_windowId = id; - - m_hWnd = (WXHWND)CreateWindowEx - ( - MakeExtendedStyle(m_windowStyle), - _T("BUTTON"), - label, - WS_VISIBLE | WS_TABSTOP | WS_CHILD, - 0, 0, 0, 0, - GetWinHwnd(parent), - (HMENU)m_windowId, - wxGetInstance(), - NULL - ); - - // Subclass again for purposes of dialog editing mode - SubclassWin(m_hWnd); - - SetFont(parent->GetFont()); - - SetSize(x, y, width, height); - - return TRUE; + wxPanel *panel = wxDynamicCast(GetParent(), wxPanel); + if ( panel ) + { + if ( panel->GetDefaultItem() == this ) + { + // don't leave the panel with invalid default item + panel->SetDefaultItem(NULL); + } + } } +// ---------------------------------------------------------------------------- +// size management including autosizing +// ---------------------------------------------------------------------------- + void wxButton::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - int currentX, currentY; - GetPosition(¤tX, ¤tY); - int x1 = x; - int y1 = y; - if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - x1 = currentX; - if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - y1 = currentY; + int currentX, currentY; + GetPosition(¤tX, ¤tY); + int x1 = x; + int y1 = y; + if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + x1 = currentX; + if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + y1 = currentY; - AdjustForParentClientOrigin(x1, y1, sizeFlags); + AdjustForParentClientOrigin(x1, y1, sizeFlags); - int actualWidth = width; - int actualHeight = height; - int ww, hh; - GetSize(&ww, &hh); + int actualWidth = width; + int actualHeight = height; + int ww, hh; + GetSize(&ww, &hh); - int current_width; - int cyf; - wxChar buf[300]; - GetWindowText((HWND) GetHWND(), buf, 300); - GetTextExtent(buf, ¤t_width, &cyf,NULL,NULL, - & this->GetFont()); + int current_width; + int cyf; + wxString buf = wxGetWindowText(GetHWND()); + GetTextExtent(buf, ¤t_width, &cyf, NULL, NULL, &GetFont()); - // If we're prepared to use the existing width, then... - if (width == -1 && ((sizeFlags & wxSIZE_AUTO_WIDTH) != wxSIZE_AUTO_WIDTH)) - actualWidth = ww; - else if (width == -1) - { - int cx; - int cy; - wxGetCharSize(GetHWND(), &cx, &cy, & this->GetFont()); - actualWidth = (int)(current_width + 3*cx) ; - } - - // If we're prepared to use the existing height, then... - if (height == -1 && ((sizeFlags & wxSIZE_AUTO_HEIGHT) != wxSIZE_AUTO_HEIGHT)) - actualHeight = hh; - else if (height == -1) - { - actualHeight = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cyf); - } + // If we're prepared to use the existing width, then... + if (width == -1 && ((sizeFlags & wxSIZE_AUTO_WIDTH) != wxSIZE_AUTO_WIDTH)) + { + actualWidth = ww; + } + else if (width == -1) + { + int cx; + int cy; + wxGetCharSize(GetHWND(), &cx, &cy, & this->GetFont()); + actualWidth = (int)(current_width + 3*cx) ; + } - MoveWindow((HWND) GetHWND(), x1, y1, actualWidth, actualHeight, TRUE); + // If we're prepared to use the existing height, then... + if (height == -1 && ((sizeFlags & wxSIZE_AUTO_HEIGHT) != wxSIZE_AUTO_HEIGHT)) + { + actualHeight = hh; + } + else if (height == -1) + { + actualHeight = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cyf); + } + + MoveWindow(GetHwnd(), x1, y1, actualWidth, actualHeight, TRUE); } -void wxButton::SetDefault(void) +void wxButton::SetDefault() { - wxWindow *parent = (wxWindow *)GetParent(); - if (parent) - parent->SetDefaultItem(this); + wxWindow *parent = GetParent(); + wxPanel *panel = wxDynamicCast(parent, wxPanel); + if ( panel ) + panel->SetDefaultItem(this); - if (parent) - { - SendMessage((HWND)parent->GetHWND(), DM_SETDEFID, m_windowId, 0L); - } + if ( parent ) + { + SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L); + } - SendMessage((HWND)GetHWND(), BM_SETSTYLE, BS_DEFPUSHBUTTON, 1L); + SendMessage(GetHwnd(), BM_SETSTYLE, BS_DEFPUSHBUTTON, 1L); } -wxString wxButton::GetLabel(void) const +// ---------------------------------------------------------------------------- +// helpers +// ---------------------------------------------------------------------------- + +bool wxButton::SendClickEvent() { - GetWindowText((HWND) GetHWND(), wxBuffer, 300); - return wxString(wxBuffer); + wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); + event.SetEventObject(this); + + return ProcessCommand(event); } -void wxButton::SetLabel(const wxString& label) +void wxButton::Command(wxCommandEvent & event) { - SetWindowText((HWND) GetHWND(), (const wxChar *) label); + ProcessCommand(event); } -WXHBRUSH wxButton::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, - WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +// ---------------------------------------------------------------------------- +// event/message handlers +// ---------------------------------------------------------------------------- + +bool wxButton::MSWCommand(WXUINT param, WXWORD id) { -/* - WXHBRUSH hBrush = (WXHBRUSH) MSWDefWindowProc(message, wParam, lParam); -// ::SetTextColor((HDC) pDC, GetSysColor(COLOR_BTNTEXT)); - ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), - GetForegroundColour().Blue())); + bool processed = FALSE; + if ( param == BN_CLICKED || param == 1 ) // 1 for accelerator + { + processed = SendClickEvent(); + } - return hBrush; -*/ - // This doesn't in fact seem to make any difference at all - buttons are always - // the same colour. - ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue())); - ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue())); + return processed; +} +WXHBRUSH wxButton::OnCtlColor(WXHDC pDC, + WXHWND pWnd, + WXUINT nCtlColor, + WXUINT message, + WXWPARAM wParam, + WXLPARAM lParam) +{ wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID); - // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush - // has a zero usage count. - // NOT NOW; CHANGED. -// backgroundBrush->RealizeResource(); return (WXHBRUSH) backgroundBrush->GetResourceHandle(); } -void wxButton::Command (wxCommandEvent & event) -{ - ProcessCommand (event); -} - - diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 6788e0ceb7..7f609f7bd6 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -56,15 +56,6 @@ wxControl::wxControl() wxControl::~wxControl() { m_isBeingDeleted = TRUE; - - // 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); - } } bool wxControl::ProcessCommand(wxCommandEvent& event) diff --git a/src/msw/dcclient.cpp b/src/msw/dcclient.cpp index 3f6a4be196..b6b44efe1b 100644 --- a/src/msw/dcclient.cpp +++ b/src/msw/dcclient.cpp @@ -79,7 +79,7 @@ static PAINTSTRUCT g_paintStruct; // created in resopnse to WM_PAINT message - doing this from elsewhere is a // common programming error among wxWindows programmers and might lead to // very subtle and difficult to debug refresh/repaint bugs. - bool g_isPainting = FALSE; + int g_isPainting = 0; #endif // __WXDEBUG__ // =========================================================================== @@ -110,7 +110,11 @@ wxWindowDC::~wxWindowDC() { SelectOldObjects(m_hDC); - ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc()); + if ( !::ReleaseDC(GetWinHwnd(m_canvas), GetHdc()) ) + { + wxLogLastError("ReleaseDC"); + } + m_hDC = 0; } @@ -178,7 +182,7 @@ wxPaintDC::wxPaintDC(wxWindow *canvas) wxCHECK_RET( canvas, _T("NULL canvas in wxPaintDC ctor") ); #ifdef __WXDEBUG__ - if ( !g_isPainting ) + if ( g_isPainting <= 0 ) { wxFAIL_MSG( _T("wxPaintDC may be created only in EVT_PAINT handler!") ); @@ -208,6 +212,8 @@ wxPaintDC::~wxPaintDC() { if ( m_hDC ) { + SelectOldObjects(m_hDC); + size_t index; wxPaintDCInfo *info = FindInCache(&index); @@ -220,6 +226,9 @@ wxPaintDC::~wxPaintDC() ms_cache.Remove(index); } //else: cached DC entry is still in use + + // prevent the base class dtor from ReleaseDC()ing it again + m_hDC = 0; } } diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 7870d6aebe..dde02e52a8 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -171,9 +171,10 @@ wxDialog::~wxDialog() wxTopLevelWindows.DeleteObject(this); + Show(FALSE); + if (m_modalShowing) { - Show(FALSE); // For some reason, wxWindows can activate another task altogether // when a frame is destroyed after a modal dialog has been invoked. // Try to bring the parent to the top. @@ -185,14 +186,10 @@ wxDialog::~wxDialog() } m_modalShowing = FALSE; - if ( GetHWND() ) - ShowWindow((HWND) GetHWND(), SW_HIDE); if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL ) wxModelessWindows.DeleteObject(this); - UnsubclassWin(); - // If this is the last top-level window, exit. if (wxTheApp && (wxTopLevelWindows.Number() == 0)) { diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index a8a91ee309..6a16a74ff4 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -9,6 +9,14 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ #pragma implementation "listctrl.h" #endif @@ -24,31 +32,43 @@ #include "wx/wx.h" #endif -#if defined(__WIN95__) +#ifdef __WIN95__ #include "wx/listctrl.h" #include "wx/log.h" #include "wx/msw/private.h" -#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) +#ifdef __GNUWIN32__ + #include "wx/msw/gnuwin32/extra.h" +#else #include #endif -#ifndef __TWIN32__ - #ifdef __GNUWIN32__ - #include "wx/msw/gnuwin32/extra.h" - #endif -#endif +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem); static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& tvItem, HWND getFullInfo = 0); +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl) IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject) #endif // USE_SHARED_LIBRARY +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxListCtrl construction +// ---------------------------------------------------------------------------- + wxListCtrl::wxListCtrl() { m_imageListNormal = NULL; @@ -96,19 +116,33 @@ bool wxListCtrl::Create(wxWindow *parent, m_windowId = (id == -1) ? NewControlId() : id; - DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP; + DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP | + LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS; + if ( wxStyleHasBorder(m_windowStyle) ) + wstyle |= WS_BORDER; + m_baseStyle = wstyle; + + if ( !DoCreateControl(x, y, width, height) ) + return FALSE; + + if (parent) + parent->AddChild(this); + + return TRUE; +} + +bool wxListCtrl::DoCreateControl(int x, int y, int w, int h) +{ + DWORD wstyle = m_baseStyle; bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &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) ) + if ( want3D ) wstyle |= WS_BORDER; - wstyle |= LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS ; - m_baseStyle = wstyle; - long oldStyle = 0; // Dummy wstyle |= ConvertToMSWStyle(oldStyle, m_windowStyle); @@ -117,13 +151,14 @@ bool wxListCtrl::Create(wxWindow *parent, WC_LISTVIEW, _T(""), wstyle, - x, y, width, height, - (HWND) parent->GetHWND(), + x, y, w, h, + GetWinHwnd(GetParent()), (HMENU)m_windowId, wxGetInstance(), NULL); - if ( !m_hWnd ) { + if ( !m_hWnd ) + { wxLogError(_T("Can't create list control window.")); return FALSE; @@ -134,22 +169,40 @@ bool wxListCtrl::Create(wxWindow *parent, #ifdef ListView_SetExtendedListViewStyle if ( wstyle & LVS_REPORT ) { - ListView_SetExtendedListViewStyle((HWND)GetHWND(), - LVS_EX_FULLROWSELECT); + ListView_SetExtendedListViewStyle(GetHwnd(), + LVS_EX_FULLROWSELECT); } #endif // ListView_SetExtendedListViewStyle wxSystemSettings settings; SetBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_WINDOW)); - SetForegroundColour(parent->GetForegroundColour()); + SetForegroundColour(GetParent()->GetForegroundColour()); - if (parent) parent->AddChild(this); - - SubclassWin((WXHWND) m_hWnd); + SubclassWin(m_hWnd); return TRUE; } +void wxListCtrl::UpdateStyle() +{ + if ( GetHWND() ) + { + // The new window view style + long dummy; + DWORD dwStyleNew = ConvertToMSWStyle(dummy, m_windowStyle); + dwStyleNew |= m_baseStyle; + + // Get the current window style. + DWORD dwStyleOld = ::GetWindowLong(GetHwnd(), GWL_STYLE); + + // Only set the window style if the view bits have changed. + if ( dwStyleOld != dwStyleNew ) + { + ::SetWindowLong(GetHwnd(), GWL_STYLE, dwStyleNew); + } + } +} + wxListCtrl::~wxListCtrl() { if (m_textCtrl) @@ -161,6 +214,10 @@ wxListCtrl::~wxListCtrl() } } +// ---------------------------------------------------------------------------- +// set/get/change style +// ---------------------------------------------------------------------------- + // Add or remove a single window style void wxListCtrl::SetSingleStyle(long style, bool add) { @@ -170,11 +227,11 @@ void wxListCtrl::SetSingleStyle(long style, bool add) if ( add ) { if ( style & wxLC_MASK_TYPE) - flag = flag & ~wxLC_MASK_TYPE ; + flag = flag & ~wxLC_MASK_TYPE; if ( style & wxLC_MASK_ALIGN ) - flag = flag & ~wxLC_MASK_ALIGN ; + flag = flag & ~wxLC_MASK_ALIGN; if ( style & wxLC_MASK_SORT ) - flag = flag & ~wxLC_MASK_SORT ; + flag = flag & ~wxLC_MASK_SORT; } if ( flag & style ) @@ -192,7 +249,7 @@ void wxListCtrl::SetSingleStyle(long style, bool add) m_windowStyle = flag; - RecreateWindow(); + UpdateStyle(); } // Set the whole window style @@ -200,61 +257,7 @@ void wxListCtrl::SetWindowStyleFlag(long flag) { m_windowStyle = flag; - RecreateWindow(); -} - -void wxListCtrl::RecreateWindow() -{ - if ( GetHWND() ) - { - long oldStyle = 0; - long style = ConvertToMSWStyle(oldStyle, m_windowStyle); - style |= m_baseStyle; - // ::SetWindowLong((HWND) GetHWND(), GWL_STYLE, style); - - // The following recreation of the window appears to be necessary - // because SetWindowLong doesn't seem to do it. - - int x, y, width, height; - GetPosition(&x, &y); - GetSize(&width, &height); - - UnsubclassWin(); - ::DestroyWindow((HWND) GetHWND()); - - // Experimental - // Recreate the ListView control: unfortunately I can't - // make it work by using SetWindowLong. - bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ; - HWND hWndListControl = CreateWindowEx(exStyle, - WC_LISTVIEW, - _T(""), - style, - x, y, width, height, - (HWND) GetParent()->GetHWND(), - (HMENU)m_windowId, - wxGetInstance(), - NULL ); - - m_hWnd = (WXHWND) hWndListControl; - SubclassWin((WXHWND) m_hWnd); - -#ifdef ListView_SetExtendedListViewStyle - if ( style & LVS_REPORT ) - { - ListView_SetExtendedListViewStyle((HWND)GetHWND(), - LVS_EX_FULLROWSELECT); - } -#endif // ListView_SetExtendedListViewStyle - - if ( m_imageListNormal ) - SetImageList(m_imageListNormal, wxIMAGE_LIST_NORMAL); - if ( m_imageListSmall ) - SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL); - if ( m_imageListState ) - SetImageList(m_imageListState, wxIMAGE_LIST_STATE); - } + UpdateStyle(); } // Can be just a single style, or a bitlist @@ -358,6 +361,10 @@ long wxListCtrl::ConvertToMSWStyle(long& oldStyle, long style) const return wstyle; } +// ---------------------------------------------------------------------------- +// accessors +// ---------------------------------------------------------------------------- + // Sets the background colour (GetBackgroundColour already implicit in // wxWindow class) bool wxListCtrl::SetBackgroundColour(const wxColour& col) @@ -365,7 +372,7 @@ bool wxListCtrl::SetBackgroundColour(const wxColour& col) if ( !wxWindow::SetBackgroundColour(col) ) return FALSE; - ListView_SetBkColor((HWND) GetHWND(), PALETTERGB(col.Red(), col.Green(), col.Blue())); + ListView_SetBkColor(GetHwnd(), PALETTERGB(col.Red(), col.Green(), col.Blue())); return TRUE; } @@ -385,7 +392,7 @@ bool wxListCtrl::GetColumn(int col, wxListItem& item) const lvCol.cchTextMax = 512; } - bool success = (ListView_GetColumn((HWND) GetHWND(), col, & lvCol) != 0); + bool success = (ListView_GetColumn(GetHwnd(), col, & lvCol) != 0); // item.m_subItem = lvCol.iSubItem; item.m_width = lvCol.cx; @@ -447,13 +454,13 @@ bool wxListCtrl::SetColumn(int col, wxListItem& item) } lvCol.mask |= LVCF_SUBITEM; lvCol.iSubItem = col; - return (ListView_SetColumn((HWND) GetHWND(), col, & lvCol) != 0); + return (ListView_SetColumn(GetHwnd(), col, & lvCol) != 0); } // Gets the column width int wxListCtrl::GetColumnWidth(int col) const { - return ListView_GetColumnWidth((HWND) GetHWND(), col); + return ListView_GetColumnWidth(GetHwnd(), col); } // Sets the column width @@ -469,7 +476,7 @@ bool wxListCtrl::SetColumnWidth(int col, int width) else if ( width2 == wxLIST_AUTOSIZE_USEHEADER) width2 = LVSCW_AUTOSIZE_USEHEADER; - return (ListView_SetColumnWidth((HWND) GetHWND(), col2, width2) != 0); + return (ListView_SetColumnWidth(GetHwnd(), col2, width2) != 0); } // Gets the number of items that can fit vertically in the @@ -478,7 +485,7 @@ bool wxListCtrl::SetColumnWidth(int col, int width) // or small icon view) int wxListCtrl::GetCountPerPage(void) const { - return ListView_GetCountPerPage((HWND) GetHWND()); + return ListView_GetCountPerPage(GetHwnd()); } // Gets the edit control for editing labels. @@ -512,7 +519,7 @@ bool wxListCtrl::GetItem(wxListItem& info) const } if (info.m_mask & wxLIST_MASK_DATA) - lvItem.mask |= LVIF_PARAM ; + lvItem.mask |= LVIF_PARAM; if ( info.m_mask & wxLIST_MASK_STATE ) { @@ -544,7 +551,7 @@ bool wxListCtrl::SetItem(wxListItem& info) LV_ITEM item; wxConvertToMSWListItem(this, info, item); item.cchTextMax = 0; - return (ListView_SetItem((HWND) GetHWND(), &item) != 0); + return (ListView_SetItem(GetHwnd(), &item) != 0); } long wxListCtrl::SetItem(long index, int col, const wxString& label, int imageId) @@ -568,7 +575,7 @@ int wxListCtrl::GetItemState(long item, long stateMask) const { wxListItem info; - info.m_mask = wxLIST_MASK_STATE ; + info.m_mask = wxLIST_MASK_STATE; info.m_stateMask = stateMask; info.m_itemId = item; @@ -583,7 +590,7 @@ bool wxListCtrl::SetItemState(long item, long state, long stateMask) { wxListItem info; - info.m_mask = wxLIST_MASK_STATE ; + info.m_mask = wxLIST_MASK_STATE; info.m_state = state; info.m_stateMask = stateMask; info.m_itemId = item; @@ -596,7 +603,7 @@ bool wxListCtrl::SetItemImage(long item, int image, int selImage) { wxListItem info; - info.m_mask = wxLIST_MASK_IMAGE ; + info.m_mask = wxLIST_MASK_IMAGE; info.m_image = image; info.m_itemId = item; @@ -608,7 +615,7 @@ wxString wxListCtrl::GetItemText(long item) const { wxListItem info; - info.m_mask = wxLIST_MASK_TEXT ; + info.m_mask = wxLIST_MASK_TEXT; info.m_itemId = item; if (!GetItem(info)) @@ -621,7 +628,7 @@ void wxListCtrl::SetItemText(long item, const wxString& str) { wxListItem info; - info.m_mask = wxLIST_MASK_TEXT ; + info.m_mask = wxLIST_MASK_TEXT; info.m_itemId = item; info.m_text = str; @@ -633,7 +640,7 @@ long wxListCtrl::GetItemData(long item) const { wxListItem info; - info.m_mask = wxLIST_MASK_DATA ; + info.m_mask = wxLIST_MASK_DATA; info.m_itemId = item; if (!GetItem(info)) @@ -646,7 +653,7 @@ bool wxListCtrl::SetItemData(long item, long data) { wxListItem info; - info.m_mask = wxLIST_MASK_DATA ; + info.m_mask = wxLIST_MASK_DATA; info.m_itemId = item; info.m_data = data; @@ -667,9 +674,9 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const code2 = LVIR_LABEL; #ifdef __WXWINE__ - bool success = (ListView_GetItemRect((HWND) GetHWND(), (int) item, &rect2 ) != 0); + bool success = (ListView_GetItemRect(GetHwnd(), (int) item, &rect2 ) != 0); #else - bool success = (ListView_GetItemRect((HWND) GetHWND(), (int) item, &rect2, code2) != 0); + bool success = (ListView_GetItemRect(GetHwnd(), (int) item, &rect2, code2) != 0); #endif rect.x = rect2.left; @@ -684,7 +691,7 @@ bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const { POINT pt; - bool success = (ListView_GetItemPosition((HWND) GetHWND(), (int) item, &pt) != 0); + bool success = (ListView_GetItemPosition(GetHwnd(), (int) item, &pt) != 0); pos.x = pt.x; pos.y = pt.y; return success; @@ -693,13 +700,13 @@ bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const // Sets the item position. bool wxListCtrl::SetItemPosition(long item, const wxPoint& pos) { - return (ListView_SetItemPosition((HWND) GetHWND(), (int) item, pos.x, pos.y) != 0); + return (ListView_SetItemPosition(GetHwnd(), (int) item, pos.x, pos.y) != 0); } // Gets the number of items in the list control int wxListCtrl::GetItemCount(void) const { - return ListView_GetItemCount((HWND) GetHWND()); + return ListView_GetItemCount(GetHwnd()); } // Retrieves the spacing between icons in pixels. @@ -707,19 +714,19 @@ int wxListCtrl::GetItemCount(void) const // view, otherwise the large icon view. int wxListCtrl::GetItemSpacing(bool isSmall) const { - return ListView_GetItemSpacing((HWND) GetHWND(), (BOOL) isSmall); + return ListView_GetItemSpacing(GetHwnd(), (BOOL) isSmall); } // Gets the number of selected items in the list control int wxListCtrl::GetSelectedItemCount(void) const { - return ListView_GetSelectedCount((HWND) GetHWND()); + return ListView_GetSelectedCount(GetHwnd()); } // Gets the text colour of the listview wxColour wxListCtrl::GetTextColour(void) const { - COLORREF ref = ListView_GetTextColor((HWND) GetHWND()); + COLORREF ref = ListView_GetTextColor(GetHwnd()); wxColour col(GetRValue(ref), GetGValue(ref), GetBValue(ref)); return col; } @@ -727,14 +734,14 @@ wxColour wxListCtrl::GetTextColour(void) const // Sets the text colour of the listview void wxListCtrl::SetTextColour(const wxColour& col) { - ListView_SetTextColor((HWND) GetHWND(), PALETTERGB(col.Red(), col.Blue(), col.Green())); + ListView_SetTextColor(GetHwnd(), PALETTERGB(col.Red(), col.Blue(), col.Green())); } // Gets the index of the topmost visible item when in // list or report view long wxListCtrl::GetTopItem(void) const { - return (long) ListView_GetTopIndex((HWND) GetHWND()); + return (long) ListView_GetTopIndex(GetHwnd()); } // Searches for an item, starting from 'item'. @@ -769,7 +776,7 @@ long wxListCtrl::GetNextItem(long item, int geom, int state) const if ( state & wxLIST_STATE_SELECTED ) flags |= LVNI_SELECTED; - return (long) ListView_GetNextItem((HWND) GetHWND(), item, flags); + return (long) ListView_GetNextItem(GetHwnd(), item, flags); } @@ -808,11 +815,12 @@ void wxListCtrl::SetImageList(wxImageList *imageList, int which) flags = LVSIL_STATE; m_imageListState = imageList; } - ListView_SetImageList((HWND) GetHWND(), (HIMAGELIST) imageList ? imageList->GetHIMAGELIST() : 0, flags); + ListView_SetImageList(GetHwnd(), (HIMAGELIST) imageList ? imageList->GetHIMAGELIST() : 0, flags); } +// ---------------------------------------------------------------------------- // Operations -//////////////////////////////////////////////////////////////////////////// +// ---------------------------------------------------------------------------- // Arranges the items bool wxListCtrl::Arrange(int flag) @@ -827,37 +835,45 @@ bool wxListCtrl::Arrange(int flag) else if ( flag == wxLIST_ALIGN_SNAP_TO_GRID ) code = LVA_SNAPTOGRID; - return (ListView_Arrange((HWND) GetHWND(), code) != 0); + return (ListView_Arrange(GetHwnd(), code) != 0); } // Deletes an item bool wxListCtrl::DeleteItem(long item) { - return (ListView_DeleteItem((HWND) GetHWND(), (int) item) != 0); + return (ListView_DeleteItem(GetHwnd(), (int) item) != 0); } // Deletes all items bool wxListCtrl::DeleteAllItems() { - return (ListView_DeleteAllItems((HWND) GetHWND()) != 0); + return (ListView_DeleteAllItems(GetHwnd()) != 0); } // Deletes all items bool wxListCtrl::DeleteAllColumns() { - int i; - for ( i = 0; i < m_colCount; i++) + while ( m_colCount > 0 ) { - if (ListView_DeleteColumn((HWND) GetHWND(), 0) != 0) - m_colCount --; + if ( ListView_DeleteColumn(GetHwnd(), 0) == 0 ) + { + wxLogLastError("ListView_DeleteColumn"); + + return FALSE; + } + + m_colCount--; } - return (m_colCount == 0); + + wxASSERT_MSG( m_colCount == 0, _T("no columns should be left") ); + + return TRUE; } // Deletes a column bool wxListCtrl::DeleteColumn(int col) { - bool success = (ListView_DeleteColumn((HWND) GetHWND(), col) != 0); + bool success = (ListView_DeleteColumn(GetHwnd(), col) != 0); if ( success && (m_colCount > 0) ) m_colCount --; @@ -876,7 +892,7 @@ wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass) { wxASSERT( (textControlClass->IsKindOf(CLASSINFO(wxTextCtrl))) ); - HWND hWnd = (HWND) ListView_EditLabel((HWND) GetHWND(), item); + HWND hWnd = (HWND) ListView_EditLabel(GetHwnd(), item); if (m_textCtrl) { @@ -900,7 +916,7 @@ bool wxListCtrl::EndEditLabel(bool cancel) /* I don't know how to implement this: there's no such macro as ListView_EndEditLabelNow. * ??? - bool success = (ListView_EndEditLabelNow((HWND) GetHWND(), cancel) != 0); + bool success = (ListView_EndEditLabelNow(GetHwnd(), cancel) != 0); if (m_textCtrl) { @@ -918,7 +934,7 @@ bool wxListCtrl::EndEditLabel(bool cancel) // Ensures this item is visible bool wxListCtrl::EnsureVisible(long item) { - return (ListView_EnsureVisible((HWND) GetHWND(), (int) item, FALSE) != 0); + return (ListView_EnsureVisible(GetHwnd(), (int) item, FALSE) != 0); } // Find an item whose label matches this string, starting from the item after 'start' @@ -932,7 +948,7 @@ long wxListCtrl::FindItem(long start, const wxString& str, bool partial) findInfo.flags |= LVFI_STRING; findInfo.psz = WXSTRINGCAST str; - return ListView_FindItem((HWND) GetHWND(), (int) start, & findInfo); + return ListView_FindItem(GetHwnd(), (int) start, & findInfo); } // Find an item whose data matches this data, starting from the item after 'start' @@ -944,7 +960,7 @@ long wxListCtrl::FindItem(long start, long data) findInfo.flags = LVFI_PARAM; findInfo.lParam = data; - return ListView_FindItem((HWND) GetHWND(), (int) start, & findInfo); + return ListView_FindItem(GetHwnd(), (int) start, & findInfo); } // Find an item nearest this position in the specified direction, starting from @@ -967,7 +983,7 @@ long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction) else if ( direction == wxLIST_FIND_RIGHT ) findInfo.vkDirection = VK_RIGHT; - return ListView_FindItem((HWND) GetHWND(), (int) start, & findInfo); + return ListView_FindItem(GetHwnd(), (int) start, & findInfo); } // Determines which item (if any) is at the specified point, @@ -978,7 +994,7 @@ long wxListCtrl::HitTest(const wxPoint& point, int& flags) hitTestInfo.pt.x = (int) point.x; hitTestInfo.pt.y = (int) point.y; - ListView_HitTest((HWND) GetHWND(), & hitTestInfo); + ListView_HitTest(GetHwnd(), & hitTestInfo); flags = 0; if ( hitTestInfo.flags & LVHT_ABOVE ) @@ -998,7 +1014,7 @@ long wxListCtrl::HitTest(const wxPoint& point, int& flags) if ( hitTestInfo.flags & LVHT_TORIGHT ) flags |= wxLIST_HITTEST_TORIGHT; - return (long) hitTestInfo.iItem ; + return (long) hitTestInfo.iItem; } // Inserts an item, returning the index of the new item if successful, @@ -1008,7 +1024,7 @@ long wxListCtrl::InsertItem(wxListItem& info) LV_ITEM item; wxConvertToMSWListItem(this, info, item); - return (long) ListView_InsertItem((HWND) GetHWND(), & item); + return (long) ListView_InsertItem(GetHwnd(), & item); } long wxListCtrl::InsertItem(long index, const wxString& label) @@ -1087,7 +1103,7 @@ long wxListCtrl::InsertColumn(long col, wxListItem& item) lvCol.mask |= LVCF_SUBITEM; lvCol.iSubItem = col; - bool success = ListView_InsertColumn((HWND) GetHWND(), col, & lvCol) != -1; + bool success = ListView_InsertColumn(GetHwnd(), col, & lvCol) != -1; if ( success ) { m_colCount++; @@ -1124,7 +1140,7 @@ long wxListCtrl::InsertColumn(long col, const wxString& heading, int format, // to scroll. If in report view mode, y specifies the number of lines to scroll. bool wxListCtrl::ScrollList(int dx, int dy) { - return (ListView_Scroll((HWND) GetHWND(), dx, dy) != 0); + return (ListView_Scroll(GetHwnd(), dx, dy) != 0); } // Sort items. @@ -1140,9 +1156,13 @@ bool wxListCtrl::ScrollList(int dx, int dy) // data is arbitrary data to be passed to the sort function. bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data) { - return (ListView_SortItems((HWND) GetHWND(), (PFNLVCOMPARE) fn, data) != 0); + return (ListView_SortItems(GetHwnd(), (PFNLVCOMPARE) fn, data) != 0); } +// ---------------------------------------------------------------------------- +// message processing +// ---------------------------------------------------------------------------- + bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id) { if (cmd == EN_UPDATE) @@ -1159,7 +1179,8 @@ bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id) ProcessCommand(event); return TRUE; } - else return FALSE; + else + return FALSE; } bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) @@ -1191,7 +1212,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT; LV_DISPINFO *info = (LV_DISPINFO *)lParam; - wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND()); + wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd()); break; } @@ -1221,22 +1242,29 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT; LV_DISPINFO *info = (LV_DISPINFO *)lParam; - wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND()); + wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd()); if ( info->item.pszText == NULL || info->item.iItem == -1 ) event.m_cancelled = TRUE; break; } case LVN_GETDISPINFO: + return FALSE; + + // this provokes stack overflow: indeed, wxConvertFromMSWListItem() + // sends us WM_NOTIFY! As it doesn't do anything for now, just leave + // it out. +#if 0 { - // return FALSE; // TODO: some text buffering here, I think // TODO: API for getting Windows to retrieve values // on demand. eventType = wxEVT_COMMAND_LIST_GET_INFO; LV_DISPINFO *info = (LV_DISPINFO *)lParam; - wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND()); + wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd()); break; } +#endif // 0 + case LVN_INSERTITEM: { eventType = wxEVT_COMMAND_LIST_INSERT_ITEM; @@ -1264,22 +1292,53 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) return FALSE; break; } + case LVN_KEYDOWN: { - eventType = wxEVT_COMMAND_LIST_KEY_DOWN; LV_KEYDOWN *info = (LV_KEYDOWN *)lParam; - event.m_code = wxCharCodeMSWToWX(info->wVKey); + WORD wVKey = info->wVKey; + + // get the current selection + long lItem = GetNextItem(-1, + wxLIST_NEXT_ALL, + wxLIST_STATE_SELECTED); + + // or activate the selected item if any + if ( lItem != -1 && (wVKey == VK_RETURN || wVKey == VK_SPACE) ) + { + // TODO this behaviour probably should be optional + eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED; + event.m_itemIndex = lItem; + } + else + { + eventType = wxEVT_COMMAND_LIST_KEY_DOWN; + event.m_code = wxCharCodeMSWToWX(wVKey); + } break; } + + case NM_DBLCLK: + // if the user processes it in wxEVT_COMMAND_LEFT_CLICK(), don't do + // anything else + if ( wxControl::MSWOnNotify(idCtrl, lParam, result) ) + { + return TRUE; + } + + // else translate it into wxEVT_COMMAND_LIST_ITEM_ACTIVATED event + eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED; + break; + case LVN_SETDISPINFO: { eventType = wxEVT_COMMAND_LIST_SET_INFO; LV_DISPINFO *info = (LV_DISPINFO *)lParam; - wxConvertFromMSWListItem(this, event.m_item, info->item, (HWND) GetHWND()); + wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd()); break; } - default : + default: return wxControl::MSWOnNotify(idCtrl, lParam, result); } @@ -1321,6 +1380,10 @@ wxChar *wxListCtrl::AddPool(const wxString& str) return (wxChar *)node->Data(); } +// ---------------------------------------------------------------------------- +// wxListItem +// ---------------------------------------------------------------------------- + // List item structure wxListItem::wxListItem() { @@ -1359,9 +1422,9 @@ static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, L lvItem.pszText = new wxChar[513]; lvItem.cchTextMax = 512; } - // lvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM ; - lvItem.mask |= LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM ; - ::SendMessage(getFullInfo, LVM_GETITEM, 0, (LPARAM)& lvItem) ; + // lvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM; + lvItem.mask |= LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + ::SendMessage(getFullInfo, LVM_GETITEM, 0, (LPARAM)& lvItem); } if ( lvItem.mask & LVIF_STATE ) @@ -1370,27 +1433,27 @@ static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, L if ( lvItem.stateMask & LVIS_CUT) { - info.m_stateMask |= wxLIST_STATE_CUT ; + info.m_stateMask |= wxLIST_STATE_CUT; if ( lvItem.state & LVIS_CUT ) - info.m_state |= wxLIST_STATE_CUT ; + info.m_state |= wxLIST_STATE_CUT; } if ( lvItem.stateMask & LVIS_DROPHILITED) { - info.m_stateMask |= wxLIST_STATE_DROPHILITED ; + info.m_stateMask |= wxLIST_STATE_DROPHILITED; if ( lvItem.state & LVIS_DROPHILITED ) - info.m_state |= wxLIST_STATE_DROPHILITED ; + info.m_state |= wxLIST_STATE_DROPHILITED; } if ( lvItem.stateMask & LVIS_FOCUSED) { - info.m_stateMask |= wxLIST_STATE_FOCUSED ; + info.m_stateMask |= wxLIST_STATE_FOCUSED; if ( lvItem.state & LVIS_FOCUSED ) - info.m_state |= wxLIST_STATE_FOCUSED ; + info.m_state |= wxLIST_STATE_FOCUSED; } if ( lvItem.stateMask & LVIS_SELECTED) { - info.m_stateMask |= wxLIST_STATE_SELECTED ; + info.m_stateMask |= wxLIST_STATE_SELECTED; if ( lvItem.state & LVIS_SELECTED ) - info.m_state |= wxLIST_STATE_SELECTED ; + info.m_state |= wxLIST_STATE_SELECTED; } } @@ -1415,14 +1478,14 @@ static void wxConvertFromMSWListItem(const wxListCtrl *ctrl, wxListItem& info, L if (lvItem.pszText) delete[] lvItem.pszText; } - lvItem.mask = oldMask ; + lvItem.mask = oldMask; } static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ITEM& lvItem) { - lvItem.iItem = (int) info.m_itemId ; + lvItem.iItem = (int) info.m_itemId; - lvItem.iImage = info.m_image ; + lvItem.iImage = info.m_image; lvItem.lParam = info.m_data; lvItem.stateMask = 0; lvItem.state = 0; @@ -1431,10 +1494,10 @@ static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ if (info.m_mask & wxLIST_MASK_STATE) { - lvItem.mask |= LVIF_STATE ; + lvItem.mask |= LVIF_STATE; if (info.m_stateMask & wxLIST_STATE_CUT) { - lvItem.stateMask |= LVIS_CUT ; + lvItem.stateMask |= LVIS_CUT; if (info.m_state & wxLIST_STATE_CUT) lvItem.state |= LVIS_CUT; } @@ -1460,14 +1523,14 @@ static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ if (info.m_mask & wxLIST_MASK_TEXT) { - lvItem.mask |= LVIF_TEXT ; + lvItem.mask |= LVIF_TEXT; if ( ctrl->GetWindowStyleFlag() & wxLC_USER_TEXT ) { lvItem.pszText = LPSTR_TEXTCALLBACK; } else { - lvItem.pszText = WXSTRINGCAST info.m_text ; + lvItem.pszText = WXSTRINGCAST info.m_text; if ( lvItem.pszText ) lvItem.cchTextMax = info.m_text.Length(); else @@ -1475,16 +1538,19 @@ static void wxConvertToMSWListItem(const wxListCtrl *ctrl, wxListItem& info, LV_ } } if (info.m_mask & wxLIST_MASK_IMAGE) - lvItem.mask |= LVIF_IMAGE ; + lvItem.mask |= LVIF_IMAGE; if (info.m_mask & wxLIST_MASK_DATA) - lvItem.mask |= LVIF_PARAM ; + lvItem.mask |= LVIF_PARAM; } +// ---------------------------------------------------------------------------- // List event +// ---------------------------------------------------------------------------- + IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent) wxListEvent::wxListEvent(wxEventType commandType, int id) -: wxNotifyEvent(commandType, id) + : wxNotifyEvent(commandType, id) { m_code = 0; m_itemIndex = 0; @@ -1492,5 +1558,5 @@ wxListEvent::wxListEvent(wxEventType commandType, int id) m_cancelled = FALSE; } -#endif +#endif // __WIN95__ diff --git a/src/msw/statbr95.cpp b/src/msw/statbr95.cpp index 2263d1a3bb..e6a2d6dbdb 100644 --- a/src/msw/statbr95.cpp +++ b/src/msw/statbr95.cpp @@ -191,7 +191,7 @@ void wxStatusBar95::SetFieldsWidth() } if ( !StatusBar_SetParts(hwnd, m_nFields, pWidths) ) { - wxLogDebug(_T("StatusBar_SetParts failed.")); + wxLogLastError(_T("StatusBar_SetParts")); } delete [] pWidths; @@ -200,7 +200,7 @@ void wxStatusBar95::SetFieldsWidth() void wxStatusBar95::SetStatusText(const wxString& strText, int nField) { if ( !StatusBar_SetText(hwnd, nField, strText) ) { - wxLogDebug(_T("StatusBar_SetText failed")); + wxLogLastError(_T("StatusBar_SetText")); } } diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index aef9105c82..5bdaae246b 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -99,6 +99,8 @@ bool wxToolBar95::Create(wxWindow *parent, long style, const wxString& name) { + m_hWnd = 0; + m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 766391e26e..d0f8984af8 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -119,17 +119,6 @@ wxMenu *wxCurrentPopupMenu = NULL; extern wxList WXDLLEXPORT wxPendingDelete; extern wxChar wxCanvasClassName[]; -#ifdef __WXDEBUG__ - // see comments in dcclient.cpp where g_isPainting is defined - extern bool g_isPainting; - - inline static void wxStartPainting() { g_isPainting = TRUE; } - inline static void wxEndPainting() { g_isPainting = FALSE; } -#else // !debug - inline static void wxStartPainting() { } - inline static void wxEndPainting() { } -#endif // debug/!debug - // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -1421,27 +1410,16 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) case VK_RETURN: { - if ( lDlgCode & DLGC_WANTMESSAGE ) + if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown ) { // control wants to process Enter itself, don't // call IsDialogMessage() which would interpret // it return FALSE; } -#ifndef __WIN16__ - wxButton *btnDefault = GetDefaultItem(); - if ( btnDefault && !bCtrlDown ) - { - // if there is a default button, Enter should - // press it - (void)::SendMessage((HWND)btnDefault->GetHWND(), - BM_CLICK, 0, 0); - return TRUE; - } - // else: but if there is not it makes sense to make it + // else: but if it does not it makes sense to make it // work like a TAB - and that's what we do. // Note that Ctrl-Enter always works this way. -#endif } break; @@ -1688,9 +1666,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) break; case WM_PAINT: - wxStartPainting(); processed = HandlePaint(); - wxEndPainting(); break; case WM_CLOSE: @@ -1814,7 +1790,10 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case VK_RETURN: case VK_BACK: case VK_TAB: - processed = TRUE; + // but set processed to FALSE, not TRUE to still pass them to + // the control's default window proc - otherwise built-in + // keyboard handling won't work + processed = FALSE; break;