bazaar: CtrlProp, CtrlFinder, CtrlMover, CtrlPos: cleanup and get rid of Visiting interface

git-svn-id: svn://ultimatepp.org/upp/trunk@3752 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
kohait 2011-08-07 17:22:51 +00:00
parent 34e87c8269
commit 1814c7ac74
18 changed files with 149 additions and 210 deletions

View file

@ -78,46 +78,32 @@ Ctrl* CtrlFinder::GetCtrl(Ctrl& c, Point& p, int& f, const CtrlFilterType& fil)
return q;
}
void CtrlFinder::Reload()
void CtrlFinder::UpdatedSource()
{
if(IsEmpty()) return;
V::Reload();
Remove();
Get().GetParent()->AddChild(&SetPos(Get().GetPos()), &Get());
}
void CtrlFinder::Visit(Ctrl& c)
{
ASSERT(c.GetParent());
V::Visit(c);
Enable();
}
void CtrlFinder::Clear()
{
ctrl = NULL;
Remove();
V::Clear();
if(!pctrl) { ctrl = NULL; return; }
ASSERT(pctrl->GetParent());
//add the finder on top of any child in the search ctrl's parent
pctrl->GetParent()->AddChild(&SetPos(pctrl->GetPos()), pctrl);
}
void CtrlFinder::LeftDown(Point p, dword keyflags)
{
ctrl = NULL;
if(IsEmpty()) return;
if(!pctrl) return;
Point pt(p);
ctrl = GetCtrl(Get(), pt, flags, filter);
if(!ctrl) ctrl = &Get();
ctrl = GetCtrl(*pctrl, pt, flags, filter);
if(!ctrl) ctrl = pctrl;
if(!ctrl) return;
WhenLeftDown(*ctrl, p, keyflags);
Action();
}
void CtrlFinder::RightDown(Point p, dword keyflags)
{
ctrl = NULL;
if(IsEmpty()) return;
if(!pctrl) return;
Point pt(p);
ctrl = GetCtrl(Get(), pt, flags, filter);
if(!ctrl) ctrl = &Get();
ctrl = GetCtrl(*pctrl, pt, flags, filter);
if(!ctrl) ctrl = pctrl;
if(!ctrl) return;
WhenRightDown(*ctrl, p, keyflags);
Action();
}

View file

@ -5,38 +5,10 @@
using namespace Upp;
#include <Gen/Gen.h>
class MouseHookCtrl : public ParentCtrl
{
public:
typedef MouseHookCtrl CLASSNAME;
virtual void LeftDown(Point p, dword keyflags) { WhenLeftDown(p,keyflags); }
virtual void RightDown(Point p, dword keyflags) { WhenRightDown(p,keyflags); }
virtual void LeftUp(Point p, dword keyflags) { WhenLeftUp(p,keyflags); }
virtual void RightUp(Point p, dword keyflags) { WhenRightUp(p,keyflags); }
virtual void MouseMove(Point p, dword keyflags) { WhenMouseMove(p,keyflags); }
virtual void LeftRepeat(Point p, dword keyflags) { WhenLeftRepeat(p,keyflags); }
virtual void RightRepeat(Point p, dword keyflags) { WhenRightRepeat(p,keyflags); }
Callback2<Point, dword> WhenLeftDown;
Callback2<Point, dword> WhenRightDown;
Callback2<Point, dword> WhenLeftUp;
Callback2<Point, dword> WhenRightUp;
Callback2<Point, dword> WhenMouseMove;
Callback2<Point, dword> WhenLeftRepeat;
Callback2<Point, dword> WhenRightRepeat;
};
class CtrlFinder : public ParentCtrl, public Visiting<Ctrl>
class CtrlFinder : public ParentCtrl
{
public:
typedef CtrlFinder CLASSNAME;
typedef MouseHookCtrl R;
typedef Visiting<Ctrl> V;
typedef Callback3<Ctrl*&, Point&, int&> CtrlFilterType;
enum
@ -55,32 +27,37 @@ public:
DEF = VISIBLE | INVISIBLE | ENABLED | DISABLED | VIEW | FRAME | DEEP,
};
static void StdCtrlFilter(Ctrl*& q, Point& pt, int& f);
static Ctrl* ChildAtPoint(Ctrl& par, Point& pt, int& f, const CtrlFilterType& fil);
static Ctrl* GetCtrl(Ctrl& c, Point& p, int& f, const CtrlFilterType& fil);
CtrlFinder() : flags(DEF), filter(STDBACK(StdCtrlFilter)) {}
virtual void Visit(Ctrl& c);
virtual void Reload();
virtual void Clear();
virtual void UpdatedSource();
virtual void LeftDown(Point p, dword keyflags);
virtual void RightDown(Point p, dword keyflags);
void SetSource(Ctrl* c) { if(c) ASSERT(c->GetParent()); pctrl = c; ctrl = NULL; UpdatedSource(); Enable(); }
Ctrl* GetSource() const { return pctrl; }
void ClearSource() { SetSource(NULL); }
void SetCtrl(Ctrl* c) { if(c && pctrl) ASSERT(c->GetParent() == ~pctrl); ctrl = c; UpdateRefresh(); }
Ctrl* GetCtrl() const { return ctrl; }
void ClearCtrl() { SetCtrl(NULL); }
virtual Value GetData() const { return RawToValue(~ctrl); }
virtual void SetData(const Value& v) { SetCtrl(RawValue<Ctrl*>::Extract(v)); }
static void StdCtrlFilter(Ctrl*& q, Point& pt, int& f);
static Ctrl* ChildAtPoint(Ctrl& par, Point& pt, int& f, const CtrlFilterType& fil);
static Ctrl* GetCtrl(Ctrl& c, Point& p, int& f, const CtrlFilterType& fil);
Callback3<Ctrl&, Point, dword> WhenLeftDown;
Callback3<Ctrl&, Point, dword> WhenRightDown;
virtual Value GetData() const { return RawToValue(~ctrl); }
Ctrl* GetCtrl() const { return ctrl; }
void ClearCtrl() { ctrl = NULL; }
void SetCtrl(Ctrl& c) { /*ASSERT(c.GetParent());*/ ctrl = &c; }
CtrlFilterType filter; //set to NULL if should not be handled, change flags if desired
int flags;
protected:
Ptr<Ctrl> ctrl;
Ptr<Ctrl> pctrl; //the parent we search in
Ptr<Ctrl> ctrl; //the current found child
};
#endif

View file

@ -1,8 +1,7 @@
description "Find a Ctrl using a transparent Hook Ctrl, see CtrlPropTest\377";
uses
CtrlLib,
Gen;
CtrlLib;
file
CtrlFinder.h,

View file

@ -15,11 +15,11 @@ void CtrlFinderTest::OnSelect(Ctrl& c, Point p, dword keyflags)
void CtrlFinderTest::VisitCB()
{
hk.Visit(vis);
hk.SetSource(&vis);
}
void CtrlFinderTest::ClearCB()
{
hk.Clear();
hk.ClearSource();
}
void CtrlFinderTest::EnableCB()
{
@ -87,7 +87,7 @@ CtrlFinderTest::CtrlFinderTest()
ViewCB();
hk.WhenLeftDown = THISBACK(OnSelect);
hk.Visit(vis);
hk.SetSource(&vis);
}
GUI_APP_MAIN

View file

@ -28,10 +28,10 @@ Point CtrlMover::GetOffset(const Ctrl& c, const Ctrl& q)
void CtrlMover::OnCtrlLeft(Ctrl& c, Point p, dword keyflags)
{
if(&c == &rc) { rc.Remove(); return; }
if(&c == &Get()) { rc.Remove(); return; } //mat not move base
if(c.InFrame()) return; //may not move frames
rc.Remove();
if(&c == &rc) return;
if(&c == ~pctrl) return; //mat not move base
Add(rc.SizePos());
//if c is frame: rect in parents window,
@ -39,7 +39,7 @@ void CtrlMover::OnCtrlLeft(Ctrl& c, Point p, dword keyflags)
Rect r = c.GetRect();
if(c.InView())
r.Offset(c.GetParent()->GetView().TopLeft());
r.Offset(GetOffset(*c.GetParent(), Get()));
r.Offset(GetOffset(*c.GetParent(), *pctrl));
rc.SetData(r);
Action();
@ -47,16 +47,14 @@ void CtrlMover::OnCtrlLeft(Ctrl& c, Point p, dword keyflags)
void CtrlMover::OnRectChange()
{
if(IsEmpty()) { rc.Remove(); return; }
if(!GetCtrl()) return;
Ctrl& c = *GetCtrl();
if(!pctrl || !ctrl) { rc.Remove(); return; }
Rect r = rc.GetData();
r.Offset(-GetOffset(*c.GetParent(), Get()));
if(c.InView())
r.Offset(-c.GetParent()->GetView().TopLeft());
r.Offset(-GetOffset(*ctrl->GetParent(), *pctrl));
if(ctrl->InView())
r.Offset(-ctrl->GetParent()->GetView().TopLeft());
c.SetRect(r);
ctrl->SetRect(r);
Action();
}
@ -67,9 +65,8 @@ void CtrlMover::OnMissed(Point p, dword keyflags)
void CtrlMover::Updated()
{
Ctrl* c = GetCtrl();
if(!c) return;
rc.SetData(c->GetRect());
if(!pctrl || !ctrl) { rc.Remove(); return; }
rc.SetData(ctrl->GetRect());
}
void CtrlMover::State(int reason)
@ -78,24 +75,6 @@ void CtrlMover::State(int reason)
if(!IsEnabled()) rc.Remove();
}
void CtrlMover::Visit(Ctrl& c)
{
rc.Remove();
V::Visit(c);
}
void CtrlMover::Clear()
{
V::Clear();
rc.Remove();
}
void CtrlMover::Reload()
{
if(IsEmpty()) return;
V::Reload();
}
CtrlMover::CtrlMover()
{
WhenLeftDown = THISBACK(OnCtrlLeft);

View file

@ -12,12 +12,8 @@ class CtrlMover : public CtrlFinder
{
public:
typedef CtrlMover CLASSNAME;
typedef CtrlFinder V;
CtrlMover();
virtual void Visit(Ctrl& c);
virtual void Clear();
virtual void Reload();
CtrlMover();
virtual void State(int reason);
virtual void Updated();

View file

@ -16,11 +16,11 @@ void CtrlMoverTest::OnSelect(Ctrl& c, Point p, dword keyflags)
void CtrlMoverTest::VisitCB()
{
hk.Visit(vis);
hk.SetSource(&vis);
}
void CtrlMoverTest::ClearCB()
{
hk.Clear();
hk.ClearSource();
}
void CtrlMoverTest::EnableCB()
{
@ -87,7 +87,7 @@ CtrlMoverTest::CtrlMoverTest()
ViewCB();
hk.WhenLeftDown = THISBACK(OnSelect);
hk.Visit(vis);
hk.SetSource(&vis);
}
GUI_APP_MAIN

View file

@ -90,12 +90,12 @@ void CtrlPos::Paint(Draw& w)
if(!IsTransparent())
w.DrawRect(0,0,sz.cx,sz.cy, SColorFace());
if(IsEnabled() && !IsEmpty())
DrawHintFrame(w, Get(), Get(), LtGray());
if(IsEnabled() && pctrl)
DrawHintFrame(w, *pctrl, *pctrl, LtGray());
if(!GetCtrl()) return;
Ctrl& c = *GetCtrl();
if(&c == &Get()) return;
if(!ctrl) return;
Ctrl& c = *ctrl;
if(&c == pctrl) return;
Rect r = c.GetRect();
Rect _r = c.GetParent()->GetView();
@ -103,7 +103,7 @@ void CtrlPos::Paint(Draw& w)
if(c.InView())
r.Offset(_r.TopLeft());
Point op = CtrlMover::GetOffset(*(c.GetParent()), Get());
Point op = CtrlMover::GetOffset(*c.GetParent(), *pctrl);
r.Offset(op);
_r.Offset(op);
@ -125,10 +125,10 @@ void CtrlPos::LeftDown(Point p, dword keyflags)
moving = false;
pressed = (keyflags & K_MOUSELEFT);
if(GetCtrl())
if(ctrl)
{
Ctrl& c = *ctrl;
//if already found prepare moving
Ctrl& c = *GetCtrl();
ASSERT(!c.InFrame());
xpos = c.GetPos();
xp = p;
@ -138,7 +138,7 @@ void CtrlPos::LeftDown(Point p, dword keyflags)
if(c.InView())
r.Offset(_r.TopLeft());
Point op = CtrlMover::GetOffset(*(c.GetParent()), Get());
Point op = CtrlMover::GetOffset(*c.GetParent(), *pctrl);
r.Offset(op);
_r.Offset(op);
@ -161,12 +161,12 @@ void CtrlPos::LeftDown(Point p, dword keyflags)
}
}
CtrlFinder::LeftDown(p, keyflags);
if(GetCtrl() == &Get()) //may not move base
if(ctrl == pctrl) //may not move base
{
ClearCtrl();
Action();
}
if(GetCtrl() && GetCtrl()->InFrame())
if(ctrl && ctrl->InFrame())
{
ClearCtrl(); //may not move frames
Action();
@ -182,8 +182,8 @@ void CtrlPos::MouseMove(Point p, dword keyflags)
pressed = (keyflags & K_MOUSELEFT);
//int m = RectCtrl::GetMode(r, p, keyflags, style->handsize);
//ci = RectCtrl::SetCursor(m, keyflags);
if(!GetCtrl()) return;
Ctrl& c = *GetCtrl();
if(!ctrl) return;
Ctrl& c = *ctrl;
if(pressed && mode != RectCtrl::NONE)
{
@ -197,19 +197,19 @@ void CtrlPos::MouseMove(Point p, dword keyflags)
Rect r = LogPosPopUp::CtrlRect(xpos, q->GetSize());
if(c.InView())
r.Offset(c.GetParent()->GetView().TopLeft());
Point ops = CtrlMover::GetOffset(*(c.GetParent()), Get());
Point ops = CtrlMover::GetOffset(*(c.GetParent()), *pctrl);
r.Offset(ops);
c.Remove(); //prevent moving control from finding when searching new parent
Point pt(p);
int ft(flags); flags |= (DEEP | NEST);
Ctrl* pc = GetCtrl(Get(), pt, flags, filter);
Ctrl* pc = GetCtrl(*pctrl, pt, flags, filter);
flags &= ~(DEEP | NEST); flags |= (ft & DEEP); //restore DEEP flag from save, NEST is ours
if(!pc) pc = &Get();
if(!pc) pc = pctrl;
if(pc != q)
{
r.Offset(-pc->GetView().TopLeft());
Point opd = CtrlMover::GetOffset(*pc, Get());
Point opd = CtrlMover::GetOffset(*pc, *pctrl);
r.Offset(-opd);
xpos = LogPosPopUp::MakeLogPos(xpos, r, pc->GetSize());
@ -278,7 +278,7 @@ void CtrlPos::RightDown(Point p, dword keyflags)
Ctrl* pc = GetCtrl()->GetParent();
r.Offset(-pc->GetView().TopLeft());
Point opd = CtrlMover::GetOffset(*pc, Get());
Point opd = CtrlMover::GetOffset(*pc, *pctrl);
r.Offset(-opd);
Ctrl::LogPos pos = LogPosPopUp::MakeLogPos(xpos, r, psz);
@ -315,6 +315,7 @@ void CtrlPos::MouseWheel(Point p, int zdelta, dword keyflags)
void CtrlPos::Updated()
{
//refresh the view of the currently selected ctrl
}
void CtrlPos::State(int reason)
@ -323,12 +324,6 @@ void CtrlPos::State(int reason)
if(!IsEnabled()) { ClearCtrl(); Refresh(); }
}
void CtrlPos::Clear()
{
V::Clear();
Refresh();
}
CtrlPos::CtrlPos()
: pressed(false), moving(false), mode(RectCtrl::NONE), g(4,4)
{

View file

@ -7,7 +7,6 @@ using namespace Upp;
#include <RectCtrl/RectCtrl.h>
#include <LogPosCtrl/LogPosCtrl.h>
#include <CtrlFinder/CtrlFinder.h>
#include <Gen/Gen.h>
//for some helpers
#include <CtrlMover/CtrlMover.h>
@ -25,8 +24,6 @@ public:
CtrlPos();
virtual void Clear();
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);

View file

@ -2,7 +2,6 @@ description "change Ctrl LogPos in a live environment\377";
uses
Core,
Gen,
RectCtrl,
LogPosCtrl,
CtrlFinder,

View file

@ -15,11 +15,11 @@ void CtrlPosTest::OnSelect(Ctrl& c, Point p, dword keyflags)
void CtrlPosTest::VisitCB()
{
hk.Visit(vis);
hk.SetSource(&vis);
}
void CtrlPosTest::ClearCB()
{
hk.Clear();
hk.ClearSource();
}
void CtrlPosTest::EnableCB()
{
@ -89,7 +89,7 @@ CtrlPosTest::CtrlPosTest()
ViewCB();
hk.WhenLeftDown = THISBACK(OnSelect);
hk.Visit(vis);
hk.SetSource(&vis);
}
GUI_APP_MAIN

View file

@ -8,7 +8,7 @@ CtrlPosTest2::CtrlPosTest2()
Sizeable().Zoomable();
hk.Visit(vis); //will add itself to vis->GetParent --> to this TopWindow with same vis.GetPos to cover it perfectly.
hk.SetSource(&vis); //will add itself to vis->GetParent --> to this TopWindow with same vis.GetPos to cover it perfectly.
}
GUI_APP_MAIN

View file

@ -4,7 +4,6 @@ uses
CtrlLib,
LogPosCtrl,
ValueCtrl,
Gen,
Property;
file

View file

@ -8,22 +8,39 @@ PropEditCtrl::PropEditCtrl()
//ac.WhenUpdateRow = THISBACK(OnUpdateRow);
}
void PropEditCtrl::Visit(Ctrl& e)
void PropEditCtrl::Updated()
{
V::Visit(e);
if(!ctrl)
{
sctrl = NULL;
ac.Clear();
vsav.Clear();
am.Clear();
return;
}
ac.Clear();
vsav.Clear();
am.Clear();
if(sctrl == ctrl)
{
for(int i = 0; i < ac.GetCount(); i++)
{
Value v;
int ii = am.Find(ac.Get(i, 0));
if(ii<0) continue;
if(!am[ii].get(v)) continue;
ac.Set(i, 1, v);
}
return;
}
sctrl = ctrl;
Ctrl& e = *ctrl;
//init local accessor map
//prefer the dynamic access
//fall back to the static accessors from Props<>
GetAccessorMapI* ami = dynamic_cast<GetAccessorMapI*>(&e);
if(ami)
am <<= ami->GetAccessorMap();
else
if(!Props<Ctrl>::SetupAccessorMap(e, am)) return;
if(ami) am <<= ami->GetAccessorMap();
else if(!Props<Ctrl>::SetupAccessorMap(e, am)) return;
for(int i = 0, k = 0; i < am.GetCount(); i++)
{
@ -88,50 +105,28 @@ void PropEditCtrl::Visit(Ctrl& e)
//ac.UpdateRefresh();
}
void PropEditCtrl::Clear()
{
V::Clear();
ac.Clear();
vsav.Clear();
}
void PropEditCtrl::Reload()
{
V::Reload();
for(int i = 0; i < ac.GetCount(); i++)
{
Value v;
int ii = am.Find(ac.Get(i, 0));
if(ii<0) continue;
if(!am[ii].get(v)) continue;
ac.Set(i, 1, v);
}
}
void PropEditCtrl::OnUpdateRow()
{
if(IsEmpty()) return;
if(!ctrl) return;
if(!ac.IsCursor()) return; //FIXME Option Focus issue
int ii = am.Find(ac.Get(0));
if(ii<0) return;
am[ii].set(ac.Get(1));
vsav.GetAdd(ac.Get(0)).a = true; //dirty
Action();
Get().UpdateActionRefresh(); //propagate user action
ctrl->UpdateActionRefresh(); //propagate user action
}
void PropEditCtrl::Restore()
void PropEditCtrl::Undo()
{
if(!IsEmpty())
{
for(int i = 0; i < vsav.GetCount(); i++)
if(vsav[i].a)
{
int ii = am.Find(vsav.GetKey(i));
if(ii<0) continue;
am[ii].set(vsav[i].b);
}
}
if(!ctrl) return;
for(int i = 0; i < vsav.GetCount(); i++)
if(vsav[i].a)
{
int ii = am.Find(vsav.GetKey(i));
if(ii<0) continue;
am[ii].set(vsav[i].b);
}
}
PropEdit::PropEdit()

View file

@ -6,26 +6,30 @@
#include <LogPosCtrl/LogPosCtrl.h>
#include <ValueCtrl/ValueCtrl.h>
#include <Gen/Gen.h>
#define LAYOUTFILE <CtrlProp/PropEdit.lay>
#include <CtrlCore/lay.h>
class PropEditCtrl : public WithPropEditLay<ParentCtrl>, public Visiting<Ctrl>
class PropEditCtrl : public WithPropEditLay<ParentCtrl>
{
public:
typedef PropEditCtrl CLASSNAME;
typedef Visiting<Ctrl> V;
PropEditCtrl();
virtual void Visit(Ctrl& e);
virtual void Reload();
virtual void Clear();
virtual void Restore();
virtual void Updated();
virtual void Undo();
void OnUpdateRow();
void SetCtrl(Ctrl* c) { ctrl = c; UpdateRefresh(); }
Ctrl* GetCtrl() const { return ctrl; }
void ClearCtrl() { SetCtrl(NULL); }
virtual Value GetData() const { return RawToValue(~ctrl); }
virtual void SetData(const Value& v) { SetCtrl(RawValue<Ctrl*>::Extract(v)); }
protected:
Ptr<Ctrl> ctrl, sctrl; //the current child, and a cache
ArrayMap<String, Tuple2<bool, Value> > vsav;
AccessorMap am;
};
@ -38,10 +42,10 @@ public:
virtual void Deactivate() {} //let other popups open
void PopUp(Ctrl* owner, Ctrl& e) { pec.Visit(e); PopUpC::PopUp(owner); }
void PopUp(Ctrl* owner, Ctrl& e) { pec.SetCtrl(&e); PopUpC::PopUp(owner); }
virtual void Rejector() { pec.Restore(); pec.Clear(); PopUpC::Rejector(); }
virtual void Acceptor() { pec.Clear(); PopUpC::Acceptor(); }
virtual void Rejector() { pec.Undo(); pec.ClearCtrl(); PopUpC::Rejector(); }
virtual void Acceptor() { pec.ClearCtrl(); PopUpC::Acceptor(); }
protected:
PropEditCtrl pec;

View file

@ -5,10 +5,16 @@ PropListCtrl::PropListCtrl()
CtrlLayout(*this);
}
void PropListCtrl::Reload()
void PropListCtrl::Updated()
{
V::Reload();
Ctrl& e = Get();
if(!ctrl)
{
gl.SetData(Null);
sl.SetData(Null);
return;
}
Ctrl& e = *ctrl;
Value v;
bool b;

View file

@ -6,19 +6,26 @@
#include <LogPosCtrl/LogPosCtrl.h>
#include <ValueCtrl/ValueCtrl.h>
#include <Gen/Gen.h>
#define LAYOUTFILE <CtrlProp/PropList.lay>
#include <CtrlCore/lay.h>
class PropListCtrl : public WithPropListLay<ParentCtrl>, public Visiting<Ctrl>
class PropListCtrl : public WithPropListLay<ParentCtrl>
{
public:
typedef PropListCtrl CLASSNAME;
typedef Visiting<Ctrl> V;
PropListCtrl();
virtual void Reload();
virtual void Updated();
void SetCtrl(Ctrl* c) { ctrl = c; UpdateRefresh(); }
Ctrl* GetCtrl() const { return ctrl; }
void ClearCtrl() { SetCtrl(NULL); }
virtual Value GetData() const { return RawToValue(~ctrl); }
virtual void SetData(const Value& v) { SetCtrl(RawValue<Ctrl*>::Extract(v)); }
protected:
Ptr<Ctrl> ctrl; //the current found child
};
class PropList : public PopUpC
@ -27,8 +34,8 @@ public:
typedef PropList CLASSNAME;
PropList();
void PopUp(Ctrl* owner, Ctrl& e) { plc.Visit(e); PopUpC::PopUp(owner); }
virtual void Acceptor() { plc.Clear(); PopUpC::Acceptor(); }
void PopUp(Ctrl* owner, Ctrl& e) { plc.SetCtrl(&e); PopUpC::PopUp(owner); }
virtual void Acceptor() { plc.ClearCtrl(); PopUpC::Acceptor(); }
protected:
PropListCtrl plc;

View file

@ -29,7 +29,7 @@ CtrlPropTest::CtrlPropTest()
AddFrame(mb);
hk.WhenRightDown = THISBACK(OnCtrlRight);
hk.Visit(vis);
hk.SetSource(&vis);
hk.Disable();
InitDummies();