1. corrected bug in MDI sample (which resulted in missing horz scrollbar)

2. define LVS_EX_FULLROWSELECT ourselves if compiler headers don't
3. wxSafeYield() will only reenable windows which had been enabled, not all
   windows in the application
4. selection in wxTreeCtrl is not broken after dnd operation
5. wxRegKey::Rename() added, regtest sample shows copying/moving/renaming keys
   and values now
6. wxListEvent accessors made const
7. wxListCtrl sets client data field in generated events under MSW too


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6269 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2000-02-24 23:33:15 +00:00
parent 18d2e17080
commit 225fe9d6ef
9 changed files with 224 additions and 168 deletions

View File

@ -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;

View File

@ -120,8 +120,6 @@ private:
class WXDLLEXPORT wxMDIChildFrame : public wxFrame
{
DECLARE_DYNAMIC_CLASS(wxMDIChildFrame)
public:
wxMDIChildFrame();
wxMDIChildFrame(wxMDIParentFrame *parent,
@ -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)
};
// ---------------------------------------------------------------------------

View File

@ -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)

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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.

View File

@ -43,7 +43,7 @@
#include <stdlib.h> // 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);

View File

@ -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;
}