diff --git a/include/wx/listctrl.h b/include/wx/listctrl.h index 41b350b38e..04e3cffb8c 100644 --- a/include/wx/listctrl.h +++ b/include/wx/listctrl.h @@ -273,20 +273,19 @@ public: wxListItem m_item; - inline int GetCode() { return m_code; } - inline long GetIndex() { return m_itemIndex; } - inline long GetOldIndex() { return m_oldItemIndex; } - inline long GetItem() { return m_itemIndex; } - inline long GetOldItem() { return m_oldItemIndex; } - inline int GetColumn() { return m_col; } - inline bool Cancelled() { return m_cancelled; } - inline wxPoint GetPoint() { return m_pointDrag; } - inline const wxString &GetLabel() const { return m_item.m_text; } - inline const wxString &GetText() const { return m_item.m_text; } - inline int GetImage() { return m_item.m_image; } - inline long GetData() { return m_item.m_data; } - inline long GetMask() { return m_item.m_mask; } - inline const wxListItem &GetItem() const { return m_item; } + int GetCode() const { return m_code; } + long GetIndex() const { return m_itemIndex; } + long GetOldIndex() const { return m_oldItemIndex; } + long GetOldItem() const { return m_oldItemIndex; } + int GetColumn() const { return m_col; } + bool Cancelled() const { return m_cancelled; } + wxPoint GetPoint() const { return m_pointDrag; } + const wxString& GetLabel() const { return m_item.m_text; } + const wxString& GetText() const { return m_item.m_text; } + int GetImage() const { return m_item.m_image; } + long GetData() const { return m_item.m_data; } + long GetMask() const { return m_item.m_mask; } + const wxListItem& GetItem() const { return m_item; } void CopyObject(wxObject& object_dest) const; diff --git a/include/wx/msw/mdi.h b/include/wx/msw/mdi.h index ebbda27e84..62d3657dd3 100644 --- a/include/wx/msw/mdi.h +++ b/include/wx/msw/mdi.h @@ -120,8 +120,6 @@ private: class WXDLLEXPORT wxMDIChildFrame : public wxFrame { - DECLARE_DYNAMIC_CLASS(wxMDIChildFrame) - public: wxMDIChildFrame(); wxMDIChildFrame(wxMDIParentFrame *parent, @@ -146,7 +144,7 @@ public: const wxString& name = wxFrameNameStr); virtual bool IsTopLevel() const { return FALSE; } - + // MDI operations virtual void Maximize(bool maximize = TRUE); virtual void Restore(); @@ -155,7 +153,6 @@ public: // Handlers bool HandleMDIActivate(long bActivate, WXHWND, WXHWND); - bool HandleSize(int x, int y, WXUINT); bool HandleWindowPosChanging(void *lpPos); bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control); @@ -172,6 +169,8 @@ protected: virtual void DoGetPosition(int *x, int *y) const; virtual void DoSetClientSize(int width, int height); virtual void InternalSetMenuBar(); + + DECLARE_DYNAMIC_CLASS(wxMDIChildFrame) }; // --------------------------------------------------------------------------- diff --git a/include/wx/msw/registry.h b/include/wx/msw/registry.h index 1161e2a285..134267eef0 100644 --- a/include/wx/msw/registry.h +++ b/include/wx/msw/registry.h @@ -144,12 +144,14 @@ public: bool Create(bool bOkIfExists = TRUE); // rename a value from old name to new one bool RenameValue(const wxChar *szValueOld, const wxChar *szValueNew); + // rename the key + bool Rename(const wxChar *szNewName); // copy value to another key possibly changing its name (by default it will // remain the same) bool CopyValue(const wxChar *szValue, wxRegKey& keyDst, const wxChar *szNewName = NULL); // copy the entire contents of the key recursively to another location - bool Copy(const wxString& strNewName); + bool Copy(const wxChar *szNewName); // same as Copy() but using a key and not the name bool Copy(wxRegKey& keyDst); // close the key (will be automatically done in dtor) diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 5a685ccc75..fbcad04649 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -954,21 +954,58 @@ int isascii( int c ) void wxEnableTopLevelWindows(bool enable) { - wxWindowList::Node *node; - for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) - node->GetData()->Enable(enable); + wxWindowList::Node *node; + for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) + node->GetData()->Enable(enable); } -// Yield to other apps/messages and disable user input +static void wxFindDisabledWindows(wxWindowList& winDisabled, wxWindow *win) +{ + wxWindowList::Node *node; + for ( node = win->GetChildren().GetFirst(); node; node = node->GetNext() ) + { + wxWindow *child = node->GetData(); + if ( child->IsEnabled() ) + { + winDisabled.Append(child); + } + + wxFindDisabledWindows(winDisabled, child); + } +} + +// Yield to other apps/messages and disable user input to all windows except +// the given one bool wxSafeYield(wxWindow *win) { - wxEnableTopLevelWindows(FALSE); - // always enable ourselves - if ( win ) - win->Enable(TRUE); - bool rc = wxYield(); - wxEnableTopLevelWindows(TRUE); - return rc; + // remember all windows we're going to (temporarily) disable + wxWindowList winDisabled; + + wxWindowList::Node *node; + for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) + { + wxWindow *winTop = node->GetData(); + wxFindDisabledWindows(winDisabled, winTop); + + winTop->Disable(); + } + + if ( win ) + { + // always enable ourselves + win->Enable(); + } + + bool rc = wxYield(); + + // don't call wxEnableTopLevelWindows(TRUE) because this will reenable even + // the window which had been disabled before, do it manually instead + for ( node = winDisabled.GetFirst(); node; node = node->GetNext() ) + { + node->GetData()->Enable(); + } + + return rc; } // Don't synthesize KeyUp events holding down a key and producing KeyDown @@ -977,7 +1014,7 @@ bool wxSafeYield(wxWindow *win) #ifndef __WXGTK__ bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) ) { - return TRUE; // detectable auto-repeat is the only mode MSW supports + return TRUE; // detectable auto-repeat is the only mode MSW supports } #endif // !wxGTK diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index 56f92fe68d..95cdee68f3 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -729,7 +729,7 @@ void wxLogDialog::OnListSelect(wxListEvent& event) // we can't just disable the control because this looks ugly under Windows // (wrong bg colour, no scrolling...), but we still want to disable // selecting items - it makes no sense here - m_listctrl->SetItemState(event.GetItem(), 0, wxLIST_STATE_SELECTED); + m_listctrl->SetItemState(event.GetIndex(), 0, wxLIST_STATE_SELECTED); } void wxLogDialog::OnOk(wxCommandEvent& WXUNUSED(event)) diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index f747968d69..544beaee43 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -51,6 +51,14 @@ (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON) #endif +#ifndef LVM_SETEXTENDEDLISTVIEWSTYLE + #define LVM_SETEXTENDEDLISTVIEWSTYLE 0x1054 +#endif + +#ifndef LVS_EX_FULLROWSELECT + #define LVS_EX_FULLROWSELECT 0x00000020 +#endif + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -196,20 +204,19 @@ bool wxListCtrl::DoCreateControl(int x, int y, int w, int h) if ( !m_hWnd ) { - wxLogError(wxT("Can't create list control window.")); + wxLogError(_("Can't create list control window, check " + "that comctl32.dll is installed.")); return FALSE; } // for comctl32.dll v 4.70+ we want to have this attribute because it's // prettier (and also because wxGTK does it like this) -#ifdef ListView_SetExtendedListViewStyle - if ( wstyle & LVS_REPORT ) + if ( (wstyle & LVS_REPORT) && wxTheApp->GetComCtl32Version() >= 470 ) { - ListView_SetExtendedListViewStyle(GetHwnd(), - LVS_EX_FULLROWSELECT); + ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, + 0, LVS_EX_FULLROWSELECT); } -#endif // ListView_SetExtendedListViewStyle SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); SetForegroundColour(GetParent()->GetForegroundColour()); @@ -1283,7 +1290,15 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) wxListEvent event(wxEVT_NULL, m_windowId); wxEventType eventType = wxEVT_NULL; + NMHDR *nmhdr = (NMHDR *)lParam; + + // almost all messages use NM_LISTVIEW + NM_LISTVIEW *nmLV = (NM_LISTVIEW *)nmhdr; + + // this is true for almost all events + event.m_item.m_data = nmLV->lParam; + switch ( nmhdr->code ) { case LVN_BEGINRDRAG: @@ -1296,12 +1311,9 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) eventType = wxEVT_COMMAND_LIST_BEGIN_DRAG; } - { - NM_LISTVIEW *hdr = (NM_LISTVIEW *)lParam; - event.m_itemIndex = hdr->iItem; - event.m_pointDrag.x = hdr->ptAction.x; - event.m_pointDrag.y = hdr->ptAction.y; - } + event.m_itemIndex = nmLV->iItem; + event.m_pointDrag.x = nmLV->ptAction.x; + event.m_pointDrag.y = nmLV->ptAction.y; break; case LVN_BEGINLABELEDIT: @@ -1309,17 +1321,14 @@ 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, GetHwnd()); - break; } + break; case LVN_COLUMNCLICK: - { - eventType = wxEVT_COMMAND_LIST_COL_CLICK; - NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam; - event.m_itemIndex = -1; - event.m_col = hdr->iSubItem; - break; - } + eventType = wxEVT_COMMAND_LIST_COL_CLICK; + event.m_itemIndex = -1; + event.m_col = nmLV->iSubItem; + break; case LVN_DELETEALLITEMS: eventType = wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS; @@ -1330,15 +1339,12 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) break; case LVN_DELETEITEM: - { - eventType = wxEVT_COMMAND_LIST_DELETE_ITEM; - NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam; - event.m_itemIndex = hdr->iItem; + eventType = wxEVT_COMMAND_LIST_DELETE_ITEM; + event.m_itemIndex = nmLV->iItem; - if ( m_hasAnyAttr ) - { - delete (wxListItemAttr *)m_attrs.Delete(hdr->iItem); - } + if ( m_hasAnyAttr ) + { + delete (wxListItemAttr *)m_attrs.Delete(nmLV->iItem); } break; @@ -1379,33 +1385,28 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case LVN_INSERTITEM: - { - eventType = wxEVT_COMMAND_LIST_INSERT_ITEM; - NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam; - event.m_itemIndex = hdr->iItem; - break; - } + eventType = wxEVT_COMMAND_LIST_INSERT_ITEM; + event.m_itemIndex = nmLV->iItem; + break; case LVN_ITEMCHANGED: + // This needs to be sent to wxListCtrl as a rather more concrete + // event. For now, just detect a selection or deselection. + if ( (nmLV->uNewState & LVIS_SELECTED) && !(nmLV->uOldState & LVIS_SELECTED) ) { - // This needs to be sent to wxListCtrl as a rather more - // concrete event. For now, just detect a selection - // or deselection. - NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam; - if ( (hdr->uNewState & LVIS_SELECTED) && !(hdr->uOldState & LVIS_SELECTED) ) - { - eventType = wxEVT_COMMAND_LIST_ITEM_SELECTED; - event.m_itemIndex = hdr->iItem; - } - else if ( !(hdr->uNewState & LVIS_SELECTED) && (hdr->uOldState & LVIS_SELECTED) ) - { - eventType = wxEVT_COMMAND_LIST_ITEM_DESELECTED; - event.m_itemIndex = hdr->iItem; - } - else - return FALSE; - break; + eventType = wxEVT_COMMAND_LIST_ITEM_SELECTED; + event.m_itemIndex = nmLV->iItem; } + else if ( !(nmLV->uNewState & LVIS_SELECTED) && (nmLV->uOldState & LVIS_SELECTED) ) + { + eventType = wxEVT_COMMAND_LIST_ITEM_DESELECTED; + event.m_itemIndex = nmLV->iItem; + } + else + { + return FALSE; + } + break; case LVN_KEYDOWN: { @@ -1429,8 +1430,10 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) eventType = wxEVT_COMMAND_LIST_KEY_DOWN; event.m_code = wxCharCodeMSWToWX(wVKey); } - break; + + event.m_item.m_data = GetItemData(lItem); } + break; case NM_DBLCLK: // if the user processes it in wxEVT_COMMAND_LEFT_CLICK(), don't do @@ -1442,46 +1445,46 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // else translate it into wxEVT_COMMAND_LIST_ITEM_ACTIVATED event // if it happened on an item (and not on empty place) + if ( nmLV->iItem == -1 ) { - NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam; - if ( hdr->iItem == -1 ) - { - // not on item - return FALSE; - } - - eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED; - event.m_itemIndex = hdr->iItem; + // not on item + return FALSE; } + + eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED; + event.m_itemIndex = nmLV->iItem; + event.m_item.m_data = GetItemData(nmLV->iItem); break; case NM_RCLICK: - /* TECH NOTE: NM_RCLICK isn't really good enough here. We want to - subclass and check for the actual WM_RBUTTONDOWN message, because - NM_RCLICK waits for the WM_RBUTTONUP message as well before firing off. - We want to have notify events for both down -and- up. */ - { - // if the user processes it in wxEVT_COMMAND_RIGHT_CLICK(), don't do - // anything else - if ( wxControl::MSWOnNotify(idCtrl, lParam, result) ) { - return TRUE; - } - - // else translate it into wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK event - LV_HITTESTINFO lvhti; - wxZeroMemory(lvhti); - - ::GetCursorPos(&(lvhti.pt)); - ::ScreenToClient(GetHwnd(),&(lvhti.pt)); - if ( ListView_HitTest(GetHwnd(),&lvhti) != -1 ) + /* TECH NOTE: NM_RCLICK isn't really good enough here. We want to + subclass and check for the actual WM_RBUTTONDOWN message, + because NM_RCLICK waits for the WM_RBUTTONUP message as well + before firing off. We want to have notify events for both down + -and- up. */ { - if ( lvhti.flags & LVHT_ONITEM ) + // if the user processes it in wxEVT_COMMAND_RIGHT_CLICK(), + // don't do anything else + if ( wxControl::MSWOnNotify(idCtrl, lParam, result) ) { - eventType = wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK; - event.m_itemIndex = lvhti.iItem; + return TRUE; + } + + // else translate it into wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK event + LV_HITTESTINFO lvhti; + wxZeroMemory(lvhti); + + ::GetCursorPos(&(lvhti.pt)); + ::ScreenToClient(GetHwnd(),&(lvhti.pt)); + if ( ListView_HitTest(GetHwnd(),&lvhti) != -1 ) + { + if ( lvhti.flags & LVHT_ONITEM ) + { + eventType = wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK; + event.m_itemIndex = lvhti.iItem; + } } } - } break; #if 0 @@ -1601,7 +1604,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // post processing // --------------- - switch ( (int)nmhdr->code ) + switch ( nmhdr->code ) { case LVN_DELETEALLITEMS: // always return TRUE to suppress all additional LVN_DELETEITEM diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index b5fef838da..4a024cd1a8 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -122,9 +122,9 @@ static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam, // wxWin macros // --------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame) - IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame) - IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow) +IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame) +IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame) +IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) EVT_SIZE(wxMDIParentFrame::OnSize) @@ -881,51 +881,6 @@ long wxMDIChildFrame::MSWWindowProc(WXUINT message, return rc; } -bool wxMDIChildFrame::HandleSize(int x, int y, WXUINT id) -{ - HWND hwnd = GetHwnd(); - - if ( !hwnd || hwnd == invalidHandle ) - { - return FALSE; - } - - switch (id) - { - case SIZEFULLSCREEN: - case SIZENORMAL: - m_iconized = FALSE; - break; - - case SIZEICONIC: - m_iconized = TRUE; - break; - } - - if ( !m_iconized ) - { - // forward WM_SIZE to status bar control -#if wxUSE_NATIVE_STATUSBAR - if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95))) - { - wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId()); - event.SetEventObject( m_frameStatusBar ); - - ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event); - } -#endif // wxUSE_NATIVE_STATUSBAR - - PositionStatusBar(); - PositionToolBar(); - - return wxWindow::HandleSize(x, y, id); - } - else - { - return FALSE; - } -} - bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd) { // In case it's e.g. a toolbar. diff --git a/src/msw/registry.cpp b/src/msw/registry.cpp index 612f021467..9686903c50 100644 --- a/src/msw/registry.cpp +++ b/src/msw/registry.cpp @@ -43,7 +43,7 @@ #include // for _MAX_PATH #ifndef _MAX_PATH - #define _MAX_PATH 512 + #define _MAX_PATH 512 #endif // our header @@ -430,7 +430,9 @@ bool wxRegKey::RenameValue(const wxChar *szValueOld, const wxChar *szValueNew) ok = FALSE; } - if ( !ok || !CopyValue(szValueOld, *this, szValueNew) ) { + if ( !ok || + !CopyValue(szValueOld, *this, szValueNew) || + !DeleteValue(szValueOld) ) { wxLogError(_("Failed to rename registry value '%s' to '%s'."), szValueOld, szValueNew); @@ -487,10 +489,65 @@ bool wxRegKey::CopyValue(const wxChar *szValue, } } -bool wxRegKey::Copy(const wxString& strNewName) +bool wxRegKey::Rename(const wxChar *szNewName) +{ + wxCHECK_MSG( !!m_strKey, FALSE, _T("registry hives can't be renamed") ); + + if ( !Exists() ) { + wxLogError(_("Registry key '%s' does not exist, cannot rename it."), + GetFullName(this)); + + return FALSE; + } + + // do we stay in the same hive? + bool inSameHive = !wxStrchr(szNewName, REG_SEPARATOR); + + // construct the full new name of the key + wxRegKey keyDst; + + if ( inSameHive ) { + // rename the key to the new name under the same parent + wxString strKey = m_strKey.BeforeLast(REG_SEPARATOR); + if ( !!strKey ) { + // don't add '\\' in the start if strFullNewName is empty + strKey += REG_SEPARATOR; + } + + strKey += szNewName; + + keyDst.SetName(GetStdKeyFromHkey(m_hRootKey), strKey); + } + else { + // this is the full name already + keyDst.SetName(szNewName); + } + + bool ok = keyDst.Create(FALSE /* fail if alredy exists */); + if ( !ok ) { + wxLogError(_("Registry key '%s' already exists."), + GetFullName(&keyDst)); + } + else { + ok = Copy(keyDst) && DeleteSelf(); + } + + if ( !ok ) { + wxLogError(_("Failed to rename the registry key '%s' to '%s'."), + GetFullName(this), GetFullName(&keyDst)); + } + else { + m_hRootKey = keyDst.m_hRootKey; + m_strKey = keyDst.m_strKey; + } + + return ok; +} + +bool wxRegKey::Copy(const wxChar *szNewName) { // create the new key first - wxRegKey keyDst(strNewName); + wxRegKey keyDst(szNewName); bool ok = keyDst.Create(FALSE /* fail if alredy exists */); if ( ok ) { ok = Copy(keyDst); diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index a613f5e12e..39277963f3 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -1549,6 +1549,10 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) event.SetEventObject(this); (void)GetEventHandler()->ProcessEvent(event); + + // if we don't do it, the tree seems to think that 2 items + // are selected simultaneously which is quite weird + TreeView_SelectDropTarget(GetHwnd(), 0); } break; }