khchen / wNim

Nim's Windows GUI Framework
MIT License
326 stars 17 forks source link

dragdrop.nim + x86_64-w64-mingw32-gcc = Error: unhandled exception: wDataObject creation failed [wDataObjectError] #106

Open arkanoid87 opened 2 years ago

arkanoid87 commented 2 years ago

I'm trying to run dragdrop.nim example on ubuntu 20.04 x86_64 as PE32+

config.nims

when defined(crosswin):
  switch("cc", "gcc")
  const arch =
    if buildCPU == "amd64":
      "x86_64"
    else:
      "i686"
  const mingwExe = arch & "-w64-mingw32-gcc"
  switch("gcc.linkerexe", mingwExe)
  switch("gcc.exe", mingwExe)
  switch("gcc.path", "/usr/bin/")
  switch("gcc.options.linker", "")
  switch("os", "windows")
  switch("define", "windows")

nim c -r -d:crosswin dragdrop.nim (straight from example, except for resource.nim)

import strformat

{.used.}
when defined(vcc):
  {.link: "wNimVcc.res".}

elif defined(cpu64):
  when defined(tcc):
    {.link: "wNimTcc64.res".}

  else:
    {.link: "wNim64.res".}

else:
  when defined(tcc):
    {.link: "wNimTcc32.res".}

  else:
    {.link: "wNim32.res".}

import wNim/[wApp, wDataObject, wAcceleratorTable, wUtils,
  wFrame, wPanel, wMenuBar, wMenu, wIcon, wBitmap,
  wStatusBar, wStaticText, wTextCtrl, wListBox, wStaticBitmap]

type
  MenuID = enum
    idText = wIdUser, idFile, idImage, idCopy, idPaste, idExit

const defaultText = "You can drop text, image, or files on drop target."
const defaultFile = ["dragdrop.exe"]
const defaultImage = staticRead(r"images/logo.png")

let app = App(wSystemDpiAware)
var data = DataObject(defaultText)

let frame = Frame(title="wNim Drag-Drop Demo", size=(600, 350),
  style=wDefaultFrameStyle or wDoubleBuffered)
frame.icon = Icon("", 0) # load icon from exe file.

let statusBar = StatusBar(frame)
let menuBar = MenuBar(frame)
let panel = Panel(frame)

let menu = Menu(menuBar, "&File")
menu.append(idText, "Load &Text", "Loads default text as current data.")
menu.append(idFile, "Load &File", "Loads exefile as current data.")
menu.append(idImage, "Load &Image", "Loads default image as current data.")
menu.appendSeparator()
menu.append(idCopy, "&Copy\tCtrl+C", "Copy current data to clipboard.")
menu.append(idPaste, "&Paste\tCtrl+V", "Paste data from clipboard.")
menu.appendSeparator()
menu.append(idExit, "E&xit", "Exit the program.")

let accel = AcceleratorTable()
accel.add(wAccelCtrl, wKey_C, idCopy)
accel.add(wAccelCtrl, wKey_V, idPaste)
frame.acceleratorTable = accel

let target = StaticText(panel, label="Drop Target",
  style=wBorderStatic or wAlignCentre or wAlignMiddle)
target.setDropTarget()

let source = StaticText(panel, label="Drag Source",
  style=wBorderStatic or wAlignCentre or wAlignMiddle)

let dataText = TextCtrl(panel,
  style=wInvisible or wBorderStatic or wTeMultiLine or wTeReadOnly or
  wTeRich or wTeDontWrap)

let dataList = ListBox(panel,
  style=wInvisible or wLbNoSel or wLbNeededScroll)

let dataBitmap = StaticBitmap(panel,
  style=wInvisible or wSbFit)

proc layout() =
  panel.autolayout """
    spacing: 20
    H:|-[target,source(100)]-[dataText,dataList,dataBitmap]-|
    V:|-[target]-[source(target)]-|
    V:|-[dataText,dataList,dataBitmap]-|
  """

proc displayData() =
  if data.isText():
    let text = data.getText()
    dataText.setValue(text)
    statusBar.setStatusText(fmt"Got {text.len} characters.")

    dataText.show()
    dataList.hide()
    dataBitmap.hide()

  elif data.isFiles():
    dataList.clear()
    for file in data.getFiles():
      dataList.append(file)
    statusBar.setStatusText(fmt"Got {dataList.len} files.")

    dataList.show()
    dataText.hide()
    dataBitmap.hide()

  elif data.isBitmap():
    let bmp = data.getBitmap()
    dataBitmap.setBitmap(bmp)
    statusBar.setStatusText(fmt"Got a {bmp.width}x{bmp.height} image.")

    dataBitmap.show()
    dataList.hide()
    dataText.hide()

source.wEvent_MouseMove do (event: wEvent):
  if event.leftDown():
    data.doDragDrop()

target.wEvent_DragEnter do (event: wEvent):
  var dataObject = event.getDataObject()
  if dataObject.isText() or dataObject.isFiles() or dataObject.isBitmap():
    event.setEffect(wDragCopy)
  else:
    event.setEffect(wDragNone)

target.wEvent_DragOver do (event: wEvent):
  if event.getEffect() != wDragNone:
    if event.ctrlDown:
      event.setEffect(wDragMove)
    else:
      event.setEffect(wDragCopy)

target.wEvent_Drop do (event: wEvent):
  var dataObject = event.getDataObject()
  if dataObject.isText() or dataObject.isFiles() or dataObject.isBitmap():
    # use copy constructor to copy the data.
    data = DataObject(dataObject)
    displayData()
  else:
    event.setEffect(wDragNone)

frame.idExit do ():
  delete frame

frame.idText do ():
  data = DataObject(defaultText)
  displayData()

frame.idFile do ():
  data = DataObject(defaultFile)
  displayData()

frame.idImage do ():
  data = DataObject(Bitmap(defaultImage))
  displayData()

frame.idCopy do ():
  wSetClipboard(data)
  if data.isText():
    statusBar.setStatusText(fmt"Copied {data.getText().len} characters.")

  elif data.isFiles():
    statusBar.setStatusText(fmt"Copied {data.getFiles().len} files.")

  elif data.isBitmap():
    let bmp = data.getBitmap()
    statusBar.setStatusText(fmt"Copied a {bmp.width}x{bmp.height} image.")

frame.idPaste do ():
  data = wGetClipboard()
  displayData()

panel.wEvent_Size do ():
  layout()

layout()
displayData()
frame.center()
frame.show()
app.mainLoop()

wine gui.exe

/home/arkanoid/nim/wnimtest/src/gui.nim(36) gui
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/wDataObject.nim(286) DataObject
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/wDataObject.nim(292) init
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/wDataObject.nim(138) error
Error: unhandled exception: wDataObject creation failed [wDataObjectError]

nim -v

Nim Compiler Version 1.6.4 [Linux: amd64]
Compiled at 2022-02-09
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: 7994556f3804c217035c44b453a3feec64405758
active boot switches: -d:release
arkanoid87 commented 2 years ago

UPDATE:

I've added the --app:gui flag and now the linux generated exe works on Windows10 (tested multiple demos), so the problem is apparently wine.

My target would be to develop it on linux, so I went on testing for a while:

arkanoid87 commented 2 years ago

I gave the binary to a wine dev for a quick look and he confirmed the issue and suggested me to take it to bugs.winehq.org

arkanoid87 commented 2 years ago

I've compiled all examples and only 3 are affected by this problem:

$ wine rebar.exe 
/home/arkanoid/nim/wnimtest/wNim/examples/rebar.nim(55) rebar
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wComboBox.nim(271) ComboBox
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wComboBox.nim(297) init
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wTextCtrl.nim(988) TextCtrl
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wTextCtrl.nim(993) init
Error: unhandled exception: cannot wrap this textctrl. [wError]

$ wine demo.exe 
/home/arkanoid/nim/wnimtest/wNim/examples/demo.nim(45) demo
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wComboBox.nim(271) ComboBox
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wComboBox.nim(297) init
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wTextCtrl.nim(988) TextCtrl
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/controls/wTextCtrl.nim(993) init
Error: unhandled exception: cannot wrap this textctrl. [wError]

$ wine dragdrop.exe 
/home/arkanoid/nim/wnimtest/wNim/examples/dragdrop.nim(25) dragdrop
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/wDataObject.nim(286) DataObject
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/wDataObject.nim(292) init
/home/arkanoid/.nimble/pkgs/wnim-0.13.1/wNim/private/wDataObject.nim(138) error
Error: unhandled exception: wDataObject creation failed [wDataObjectError]

the very same binaries run correctly on windows

khchen commented 2 years ago

wDataObject used some undocumented Windows tech whitch maybe not implemented on wine.

woodgiraffe commented 1 year ago

wDataObject used some undocumented Windows tech whitch maybe not implemented on wine.

👋 what about Error: unhandled exception: cannot wrap this textctrl. [wError] ? Same as Error: unhandled exception: wDataObject creation failed [wDataObjectError] ?

wComboBox.nim not working on Wine is very sad, other widgets seem to work fine.

Thanks for this great library! Amazing work!