#if defined(dll)=0
    dim shared as hmodule dll
#endif

type PSynEdit as QSynEdit ptr
type QSynEdit extends QFrame
    protected:
    Create as function stdcall(as zstring ptr,byref as hwnd,as integer,as integer,as integer,as integer,byref as any ptr) as hwnd
    declare static function DlgProc(as hwnd,as uint,as wparam,as lparam) as lresult
    declare virtual sub CreateHandle
    declare virtual sub Dispatch(byref as QMessage)
    declare virtual sub Handler(byref as QMessage)
    public:
    declare operator cast as any ptr
    declare operator let(as string)
    declare operator cast as string
    declare constructor
    declare destructor
end type

namespace SynEdit
    function Register as zstring ptr
        return @"Delphi=QSynEdit"
    end function
end namespace

sub QSynEdit.CreateHandle
    dim as any ptr obj=0
    Create=dylibsymbol(dll,"Create")
    if Create then
       creationdata=this
       fHandle=iif(fParent,fparent->handle,0)
       Create(strptr(classname),fHandle,fleft,ftop,fwidth,fheight,obj)
       if IsWindow(fHandle) then
          SetProp(fhandle,"@@@Proc",cast(wndproc,SetWindowLongPtr(fhandle,gwl_wndproc,cint(@dlgproc))))
          SetWindowLongPtr(fhandle,gwl_userdata,cint(@this))
       end if
    end if 
end sub

function QSynEdit.DlgProc(dlg as hwnd,msg as uint,wparam as wparam,lparam as lparam) as lresult
    dim as pframe f=iif(creationdata,creationdata,cast(pframe,getwindowlongptr(dlg,gwl_userdata)))
    dim as QMessage m=type(dlg,msg,wparam,lparam,0,f)
    if f then
       f->fhandle=dlg
       f->dispatch(m)
       if m.result=0 then f->handler(m)
       return m.result
    else
       f=new QSynEdit
       f->fhandle=dlg
       f->dispatch(m)
       if m.result=0 then f->handler(m)
       return m.result
    end if
    return m.result
end function

sub QSynEdit.Dispatch(byref m as QMessage)
    select case m.msg
    case wm_parentnotify
         select case loword(m.wparam)
         case wm_create
              SetWindowLongPtr(m.dlg,gwl_userdata,cint(@this))
              creationdata=0
              m.result=0
         end select
    case wm_rbuttondown
         if onMouseDown then onMouseDown(this,MK_RBUTTON,loword(m.lparam),hiword(m.lparam),m.wparam and &hffff)
         if fpopupmenu then
            dim as point pt=type(loword(m.lparam),hiword(m.lparam))
            Base.clienttoscreen(pt)
            TrackPopupMenu(fpopupmenu->handle,0,pt.x,pt.y,0,fhandle,0)
         end if
         m.result=0
    case wm_command
         if m.lparam=0 then
            SendMessage(fhandle,cm_command,loword(m.wparam),hiword(m.wparam))
         end if
         m.result=0
    case cm_command
         if onmenu then onmenu(this,m.wparam)
         m.result=0
    end select
end sub

sub QSynEdit.Handler(byref m as QMessage)
    m.result=callwindowproc(GetProp(m.dlg,"@@@Proc"),m.dlg,m.msg,m.wparam,m.lparam)
end sub

operator QSynEdit.cast as any ptr
    return @this
end operator

operator QSynEdit.let(v as string)
    SetWindowText(fhandle,v)
end operator

operator QSynEdit.cast as string
    dim as zstring ptr buff=callocate(GetWindowTextLength(fhandle)+1)
    GetWindowText(fhandle,buff,len(*buff))
    return *buff
end operator

constructor QSynEdit
    classname="TSynEdit" '"TRichEdit" "TMemo"
end constructor

destructor QSynEdit
    SetWindowText(fhandle,"") '''discard any memory from dll object
end destructor

sub synedit_initialization constructor
    dll=dylibload("delphiclasses.dll")
end sub

sub synedit_finalization destructor
    if dll then dylibfree(dll)
end sub