0

i'm trying to incorporate a derived class from WDL_VWnd. (For those that don't know, WDL is a bit like JUCE it allows to developp easily audio plugins)

so inside WDL there is a library that allows the creation of Windows windows

i'm trying to just create 1 child modal window outside the main audio plugin window.

i got 3 strange errors:

error LNK2019: unresolved external symbol "public: __thiscall WDL_VWnd::WDL_VWnd(void)" (??0WDL_VWnd@@QAE@XZ) référenced in the function "public: __thiscall testWindows::testWindows(void)" (??0testWindows@@QAE@XZ)   C:\wdl-ol2\IPlugExamples\TestWaveletsCenter2\testWindows.obj
error LNK2019: unresolved external symbol "public: int __thiscall WDL_VWnd_Painter::GSC(int)" (?GSC@WDL_VWnd_Painter@@QAEHH@Z) référenced in the function "public: virtual int __thiscall testWindows::GSC(int)" (?GSC@testWindows@@UAEHH@Z)    C:\wdl-ol2\IPlugExamples\TestWaveletsCenter2\testWindows.obj
error LNK2019: unresolved external symbol "public: virtual __thiscall WDL_VWnd::~WDL_VWnd(void)" (??1WDL_VWnd@@UAE@XZ) référenced in the function __unwindfunclet$??0testWindows@@QAE@XZ$0  C:\wdl-ol2\IPlugExamples\TestWaveletsCenter2\testWindows.obj

but the errors are not about the class TestWindows. Also WDL is very simple to install, there is not libraries to link, only simple #includes (which makes it very nice to use)

so, in the file TestWindows.h, i derivated a class from WDL_VWnd :

#ifndef _TestWindows_
#define _TestWindows_

#ifdef _WIN32
  #include <windows.h>
  #include <windowsx.h>
#else
  #include "../WDL/swell/swell.h"
#endif

#include "../WDL/wingui/virtwnd.h"


class TestWindows : public WDL_VWnd
{
public:
    TestWindows(void);
    ~TestWindows(void);

  virtual int OnMouseDown(int xpos, int ypos);
  virtual bool OnMouseDblClick(int xpos, int ypos);
  virtual void OnMouseMove(int xpos, int ypos);
  virtual void OnMouseUp(int xpos, int ypos);
  virtual int UpdateCursor(int xpos, int ypos);
  virtual bool GetToolTipString(int xpos, int ypos, char *bufOut, int bufOutSz);

  virtual bool IsDescendent(WDL_VWnd *w);
  virtual bool OnMouseWheel(int xpos, int ypos, int amt);
  virtual WDL_VWnd *VirtWndFromPoint(int xpos, int ypos, int maxdepth);

  virtual void SetChildPosition(WDL_VWnd *ch, int pos);
  virtual void AddChild(WDL_VWnd *wnd, int pos);
  virtual WDL_VWnd *GetChildByID(int id);

  virtual void RemoveChild(WDL_VWnd *wnd, bool dodel);
  virtual void OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect);
  virtual void OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect);
  virtual int GetNumChildren();
  virtual WDL_VWnd *EnumChildren(int x);
  virtual void RemoveAllChildren(bool dodel);
  virtual INT_PTR SendCommand(int command, INT_PTR parm1, INT_PTR parm2, WDL_VWnd *src);

  virtual void GetPositionInTopVWnd(RECT *r);

  virtual void RequestRedraw(RECT *r);
  virtual void testWindows::OnCaptureLost();

  virtual int GSC(int a);
protected:
  WDL_VWnd *m_parent;
  WDL_VWnd_IAccessibleBridge *m__iaccess;
  bool m_visible;
  int m_id;
  RECT m_position;
  INT_PTR m_userdata;

  HWND m_realparent;
  int m_captureidx;
  int m_lastmouseidx;
  WDL_PtrList<WDL_VWnd> *m_children;

  const char *m__iaccess_desc;

  WDL_VWnd_Painter *m_curPainter;


  WDL_DestroyState m_destroystate;
};;

#endif

here is TestWindows.cpp

#include "testWindows.h"

testWindows::testWindows() 
{ 
  m__iaccess=0;
  m__iaccess_desc=0;
  m_visible=true; m_id=0; 
  m_position.left=0; m_position.top=0; m_position.right=0; m_position.bottom=0; 
  m_parent=0;
  m_children=0;
  m_realparent=0;
  m_captureidx=-1;
  m_lastmouseidx=-1;
  m_userdata=0;
  m_curPainter=0;
}

testWindows::~testWindows() 
{ 
  if (m_children) 
  {
    m_children->Empty(true); 
    delete m_children;
  }
  if (m__iaccess) m__iaccess->Release();
}

int testWindows::GSC(int a)
{
  return m_curPainter ? m_curPainter->GSC(a) : GetSysColor(a);
}

INT_PTR testWindows::SendCommand(int command, INT_PTR parm1, INT_PTR parm2, WDL_VWnd *src)
{
  if (m_realparent)
  {
    return SendMessage(m_realparent,command,parm1,parm2);
  }
  else if (m_parent) return m_parent->SendCommand(command,parm1,parm2,src);
  return 0;
}

void testWindows::RequestRedraw(RECT *r)
{ 
  if (!IsVisible() || 
      m_position.right <= m_position.left || 
      m_position.bottom <= m_position.top) return;

  RECT r2;

  if (r)
  {
    r2=*r; 
    r2.left+=m_position.left; r2.right += m_position.left; 
    r2.top += m_position.top; r2.bottom += m_position.top;
  }
  else 
  {
    GetPositionPaintExtent(&r2);
    RECT r3;
    if (WantsPaintOver())
    {
      GetPositionPaintOverExtent(&r3);
      if (r3.left<r2.left)r2.left=r3.left;
      if (r3.top<r2.top)r2.top=r3.top;
      if (r3.right>r2.right)r2.right=r3.right;
      if (r3.bottom>r2.bottom)r2.bottom=r3.bottom;
    }
  }

  if (m_realparent)
  {
#ifdef _WIN32
    HWND hCh;
    if ((hCh=GetWindow(m_realparent,GW_CHILD)))
    {
      HRGN rgn=CreateRectRgnIndirect(&r2);
      int n=30; // limit to 30 children
      while (n-- && hCh)
      {
        if (IsWindowVisible(hCh))
        {
          RECT r;
          GetWindowRect(hCh,&r);
          ScreenToClient(m_realparent,(LPPOINT)&r);
          ScreenToClient(m_realparent,((LPPOINT)&r)+1);
          HRGN tmprgn=CreateRectRgn(r.left,r.top,r.right,r.bottom);
          CombineRgn(rgn,rgn,tmprgn,RGN_DIFF);
          DeleteObject(tmprgn);
        }
        hCh=GetWindow(hCh,GW_HWNDNEXT);
      }
      InvalidateRgn(m_realparent,rgn,FALSE);
      DeleteObject(rgn);

    }
    else
#else
  // OS X, expand region up slightly
  r2.top--;
#endif
      InvalidateRect(m_realparent,&r2,FALSE);
  }
  else if (m_parent) m_parent->RequestRedraw(&r2); 
}

bool testWindows::IsDescendent(WDL_VWnd *w)
{
  if (!w || !m_children) return false;
  int x,n=m_children->GetSize();
  for(x=0;x<n;x++) if (m_children->Get(x) == w) return true;
  for(x=0;x<n;x++) 
  {
    WDL_VWnd *tmp = m_children->Get(x);
    if (tmp && tmp->IsDescendent(w)) return true;
  }
  return false;
}

void testWindows::SetChildPosition(WDL_VWnd *ch, int pos)
{
  if (!ch || !m_children) return;
  int x;
  for(x=0;x<m_children->GetSize();x++)
  {
    if (m_children->Get(x) == ch) 
    {
      if (pos>x) pos--;
      if (pos != x)
      {
        m_children->Delete(x);
        m_children->Insert(pos,ch);
      }
      return;
    }
  }
}

void testWindows::AddChild(WDL_VWnd *wnd, int pos)
{
  if (!wnd) return;

  wnd->SetParent(this);
  if (!m_children) m_children=new WDL_PtrList<WDL_VWnd>;
  if (pos<0||pos>=m_children->GetSize()) m_children->Add(wnd);
  else m_children->Insert(pos,wnd);
  if (m__iaccess) m__iaccess->ClearCaches();
}

WDL_VWnd *testWindows::GetChildByID(int id)
{
  if (m_children) 
  {
    int x;
    for (x = 0; x < m_children->GetSize(); x ++)
      if (m_children->Get(x)->GetID()==id) return m_children->Get(x);
    WDL_VWnd *r;
    for (x = 0; x < m_children->GetSize(); x ++) if ((r=m_children->Get(x)->GetChildByID(id))) return r;
  }

  return 0;
}

void testWindows::RemoveChild(WDL_VWnd *wnd, bool dodel)
{
  int idx=m_children ? m_children->Find(wnd) : -1;
  if (idx>=0) 
  {
    if (!dodel)
    {
      WDL_VWnd *ch = m_children->Get(idx);
      if (ch) ch->SetParent(NULL);
    }
    m_children->Delete(idx,dodel);
  }
  if (m__iaccess) m__iaccess->ClearCaches();
}

void testWindows::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect)
{
  int x;
  if (m_children) for (x = m_children->GetSize()-1; x >=0; x --)
  {
    WDL_VWnd *ch=m_children->Get(x);
    if (ch->IsVisible())
    {
      RECT re;
      ch->GetPosition(&re);
      if (re.right>re.left&&re.bottom>re.top)
      {
        ch->GetPositionPaintExtent(&re);
        re.left += origin_x + m_position.left;
        re.right += origin_x + m_position.left;
        re.top += origin_y + m_position.top;
        re.bottom += origin_y + m_position.top;

        RECT cr=*cliprect;
        if (cr.left < re.left) cr.left=re.left;
        if (cr.right > re.right) cr.right=re.right;
        if (cr.top < re.top) cr.top=re.top;
        if (cr.bottom > re.bottom) cr.bottom=re.bottom;

        if (cr.left < cr.right && cr.top < cr.bottom)
        {
          ch->SetCurPainter(m_curPainter);
          ch->OnPaint(drawbm,m_position.left+origin_x,m_position.top+origin_y,&cr);
          ch->SetCurPainter(NULL);
        }
      }
    }
  }
}

void testWindows::OnPaintOver(LICE_IBitmap *drawbm, int origin_x, int origin_y, RECT *cliprect)
{
  int x;
  if (m_children) for (x = m_children->GetSize()-1; x >=0; x --)
  {
    WDL_VWnd *ch=m_children->Get(x);
    if (ch->IsVisible() && ch->WantsPaintOver())
    {
      RECT re;
      ch->GetPosition(&re);
      if (re.right>re.left && re.bottom > re.top)
      {
        ch->GetPositionPaintOverExtent(&re);
        re.left += origin_x + m_position.left;
        re.right += origin_x + m_position.left;
        re.top += origin_y + m_position.top;
        re.bottom += origin_y + m_position.top;

        RECT cr=*cliprect;

        if (cr.left < re.left) cr.left=re.left;
        if (cr.right > re.right) cr.right=re.right;
        if (cr.top < re.top) cr.top=re.top;
        if (cr.bottom > re.bottom) cr.bottom=re.bottom;

        if (cr.left < cr.right && cr.top < cr.bottom)
        {
          ch->SetCurPainter(m_curPainter);
          ch->OnPaintOver(drawbm,m_position.left+origin_x,m_position.top+origin_y,&cr);
          ch->SetCurPainter(NULL);
        }
      }
    }
  }
}

int testWindows::GetNumChildren()
{
  return m_children ? m_children->GetSize() : 0;
}

WDL_VWnd *testWindows::EnumChildren(int x)
{
  return m_children ? m_children->Get(x) : 0;
}

void testWindows::RemoveAllChildren(bool dodel)
{
  if (m_children) 
  {
    if (!dodel) // update parent pointers
    {
      int x;
      for (x = 0; x < m_children->GetSize(); x++)
      {
        WDL_VWnd *ch = m_children->Get(x);
        if (ch) ch->SetParent(NULL);
      }
    }
    m_children->Empty(dodel);
  }
}

WDL_VWnd *testWindows::VirtWndFromPoint(int xpos, int ypos, int maxdepth)
{
  int x;
  if (m_children) for (x = 0; x < m_children->GetSize(); x++)
  {
    WDL_VWnd *wnd=m_children->Get(x);
    if (wnd->IsVisible())
    {
      RECT r;
      wnd->GetPosition(&r);
      if (xpos >= r.left && xpos < r.right && ypos >= r.top && ypos < r.bottom) 
      {
        if (maxdepth!=0)
        {
          WDL_VWnd *cwnd=wnd->VirtWndFromPoint(xpos-r.left,ypos-r.top,maxdepth > 0 ? (maxdepth-1) : -1);
          if (cwnd) return cwnd;
        }
        return wnd;
      }
    }
  }
  return 0;

}

int testWindows::OnMouseDown(int xpos, int ypos) // returns TRUE if handled
{
  if (!m_children) return 0;

  WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0);
  if (!wnd) 
  {
    m_captureidx=-1;
    return 0;
  }  
  RECT r;
  wnd->GetPosition(&r);
  WDL_VWND_DCHK(chk);
  int a;
  if ((a=wnd->OnMouseDown(xpos-r.left,ypos-r.top)))
  {
    if (a<0) return -1;
    if (chk.isOK()) m_captureidx=m_children->Find(wnd);
    return 1;
  }
  return 0;
}

bool testWindows::OnMouseDblClick(int xpos, int ypos) // returns TRUE if handled
{
  WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0);
  if (!wnd) return false;
  RECT r;
  wnd->GetPosition(&r);
  return wnd->OnMouseDblClick(xpos-r.left,ypos-r.top);
}

bool testWindows::OnMouseWheel(int xpos, int ypos, int amt)
{
  WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0);
  if (!wnd) return false;
  RECT r;
  wnd->GetPosition(&r);
  return wnd->OnMouseWheel(xpos-r.left,ypos-r.top,amt);
}

bool testWindows::GetToolTipString(int xpos, int ypos, char *bufOut, int bufOutSz)
{
  WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0);
  if (!wnd) return false;

  RECT r;
  wnd->GetPosition(&r);
  return wnd->GetToolTipString(xpos-r.left,ypos-r.top,bufOut,bufOutSz);
}

int testWindows::UpdateCursor(int xpos, int ypos)
{
  WDL_VWnd *wnd=VirtWndFromPoint(xpos,ypos,0);
  if (!wnd) return 0;

  RECT r;
  wnd->GetPosition(&r);
  return wnd->UpdateCursor(xpos-r.left,ypos-r.top);
}

void testWindows::OnMouseMove(int xpos, int ypos)
{
  if (!m_children) return;

  WDL_VWnd *wnd=m_children->Get(m_captureidx);

  WDL_VWND_DCHK(chk);
  if (!wnd) 
  {
    wnd=VirtWndFromPoint(xpos,ypos,0);
    if (wnd) // todo: stuff so if the mouse goes out of the window completely, the virtualwnd gets notified
    {
      int idx=m_children->Find(wnd);
      if (idx != m_lastmouseidx)
      {
        WDL_VWnd *t=m_children->Get(m_lastmouseidx);
        if (t)
        {
          RECT r;
          t->GetPosition(&r);
          t->OnMouseMove(xpos-r.left,ypos-r.top);
        }
        if (chk.isOK()) m_lastmouseidx=idx;
      }
    }
    else
    {
      WDL_VWnd *t=m_children->Get(m_lastmouseidx);
      if (t)
      {
        RECT r;
        t->GetPosition(&r);
        t->OnMouseMove(xpos-r.left,ypos-r.top);
      }
      if (chk.isOK()) m_lastmouseidx=-1;
    }
  }

  if (wnd && chk.isOK()) 
  {
    RECT r;
    wnd->GetPosition(&r);
    wnd->OnMouseMove(xpos-r.left,ypos-r.top);
  }
}

void testWindows::OnCaptureLost()
{
  int oldcap=m_captureidx;
  m_captureidx=-1;
  if (m_children)
  {
    WDL_VWnd *wnd=m_children->Get(oldcap);
    if (wnd) 
    {
      wnd->OnCaptureLost();
    }
  }
}

void testWindows::OnMouseUp(int xpos, int ypos)
{
  int oldcap=m_captureidx;
  m_captureidx=-1; // set this before passing to children, in case a child ends up destroying us
  if (m_children)
  {
    WDL_VWnd *wnd=m_children->Get(oldcap);

    if (!wnd) 
    {
      wnd=VirtWndFromPoint(xpos,ypos,0);
    }

    if (wnd) 
    {
      RECT r;
      wnd->GetPosition(&r);
      wnd->OnMouseUp(xpos-r.left,ypos-r.top);
    }
  }
}

void testWindows::GetPositionInTopVWnd(RECT *r)
{
  GetPosition(r);
  WDL_VWnd *par=GetParent();
  while (par)
  {
    WDL_VWnd *tmp=par;
    par=par->GetParent();
    if (par)
    {
      RECT t;
      tmp->GetPosition(&t);
      r->left+=t.left;
      r->right+=t.left;
      r->top+=t.top;
      r->bottom+=t.top;
    }
  };

}
IonOne
  • 385
  • 4
  • 15

0 Answers0