Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wxWindow from wxlua to c++ #136

Open
Abooow786 opened this issue May 27, 2024 · 11 comments
Open

wxWindow from wxlua to c++ #136

Abooow786 opened this issue May 27, 2024 · 11 comments

Comments

@Abooow786
Copy link

Abooow786 commented May 27, 2024

Hey,

currently i#m working on zerobrane and wanted to add somethings to make my life easier. I added a extra window. In this window i wanted to show the frame of a different Program. With wxWidgets its possible and i already tried it but wxlua does not has all the function i need(for example retrieving the window handle and associate it with a wxwindow/wxPanel..). So i wanted to do this in c++. Got the lua5.1 source code. Added the needed functions in c++. Told lua about the new functions. Started lua, executed src/main.lua and hey everything worked. Even the environment knows the function which i wrote.

Now the Problem. I create a wxWindow object in lua with wxua. Now i want to get this object into my c++ code but it does not work. Lua says: "expected userdata, received: value at this index reflect the desired type".

My c++ Function just gets WxWindow Object in the header.

So how can i get a wxObject from lua to c++?

@pkulchenko
Copy link
Owner

@Abooow786, I can't say what's wrong, but I can suggest two things: (1) if you're interested in some specific classes, list them in your comment and we can look into exposing them in wxlua and (2) you can check existing wrappers to see if any of them do something similar. I'm sure there are some that deal with window handles, so you can check how they pass them back/from Lua code.

@Abooow786
Copy link
Author

My lua Code:

require("wx")

MyApp = wx.wxApp(false)

--creating all wxelements
frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, "wxLua Frame", wx.wxDefaultPosition, wx.wxSize(400, 300))
window = wx.wxWindow(frame, wx.wxID_ANY)
button = wx.wxButton(window, wx.wxID_ANY, "Click me", wx.wxPoint(10, 10))

function alio()
print(window)
--prints: userdata: 000000003A958308 [wxWindow(000001F8FD1A17C0, 443)] for example

--function written in c++ which gets a wxWindow*
connectWindowWithApplication(window)
end

--
function OnButtonClick(event)
alio()
end
button:Connect(wx.wxEVT_COMMAND_BUTTON_CLICKED, OnButtonClick)

--showing frame and executing loop
frame:Show(true)
MyApp:MainLoop()

My cpp Code:

void connectWindowWithApplication(sol::object window)
{
HWND hCurWnd = NULL, finalhwnd = NULL;
wxWindow* frameforhwnd = window.as<wxWindow*>();
wxProcess* process = nullptr;
wxString command = "C:\Users\CKC4FE\Desktop\Client_GUI\SCE_Libs\SciChart_SCE.exe";
wxString parameters = ""False" "False" "C:\Users\CKC4FE\Desktop\currentPlot.csv"";
int exitCode = wxExecute(command + " " + parameters, wxEXEC_ASYNC, process);
wxSleep(3);
wxPanel* test132 = new wxPanel();
}
//[put some algorithm away for copy]
//
//SendMessage(finalhwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
//ShowWindow(finalhwnd, SW_MINIMIZE);
//frameforhwnd->AssociateHandle(finalhwnd);
//SetParent(test132->GetHWND(), frameforhwnd->GetHWND());

Goal:
Executing a program(i know the function wxExecute is also in lua). Getting the Handle(here it is a windows handle, so retrieving this in wxlua was/is my first Problem. Thats why i hopped in c++) Setting this handle inside the wxWindow inside the new created wxWindow test132. Setting this window as child for the new created window inside zerobrane.

In c++ i'm working with sol to make my life easier. So there is the main Problem. Im getting a sol:object but interpreting it as a Window* gives me the stated Problem. Maybe i'm just an idiot and don't see my error.

I tried to set the window in lua as a global var. Then i extracted the var inside my c++ code. This worked but doing anything with the var leaded to another error. Im working with x64(built wxWidgtes new, built wxlua new) I#m assuming that the created wx.dll file is correct because lua 5.1 x64 can require the module and the lua file just works fine(also zerobrane here i built everything inc. socket..)

@pkulchenko
Copy link
Owner

I can't say what may be wrong here, but if you already have wxWindow object, you may be able to get its content directly. For example, here is the plugin that saves a screenshot of wxWindow object: https://github.com/pkulchenko/ZeroBranePackage/blob/master/screenshot.lua#L44-L53

@Abooow786
Copy link
Author

Hmmm tried some things but still is not working. I just tried to create a wxWindow in C++ and send it to lua. As soon as i call a function like connect(window, button..) it says that it expected a wxWindow but got a userdata. So the conversion is not doing right? Lua knows what a wxWindow is but does not save it as a userdata but as a wxWindow. So in lua i have to convert the userdata to a wxWindow Object? And something like this also has to be done when switching between lua and c++?

Does it work for you?Is it just a me Problem?

@Abooow786
Copy link
Author

So for some Idea what my comment before meant. I wrote a function giveWindow() in c++. This function just creates a wxWindow and return it.

require("wx")
ab = giveWindow()
print(ab)
userdata: 0x1aa07ce8
ab = wx.wxWindow()
print(ab)
userdata: 000000001AA08548 [wxWindow(00000205DD231050, 443)]

This is what my lua console returns. A userdata Pointer when the wxWindow object gets creates inside c++ and gets parses to lua. Also a userdata but more like a struct when created inside lua

@pkulchenko
Copy link
Owner

It looks like you do create a userdata object, but it's missing all the class/type information that wxlua manages, so it's not recognized as wxWindow object.

@Abooow786
Copy link
Author

Yes right. Thats what i meant with some ‚conversion‘ which misses. And Idea how to pull that of? wxluaT_pushuserdatatype with a function that? Did try it but could‘t get ot working.

@pkulchenko
Copy link
Owner

wxluaT_pushuserdatatype seems to be the right way, but maybe not sufficient. I'd check that you're setting up the bind class correctly; for example:

            if (wxlClass->classInfo)
            {
                const wxLuaBindClass* classInfoClass = wxluaT_getclass(L, "wxClassInfo");
                if (classInfoClass)
                {
                    wxluaT_pushuserdatatype(L, wxlClass->classInfo, *classInfoClass->wxluatype);
                    return 1;
                }
            }

Also, check wxLua_wxObject_DynamicCast, as it does type conversion, but only for "compatible" types.

@Abooow786
Copy link
Author

Hmm i just built the source code like it is. So this functionality is is not supported from the beginning? I‘m a little unsecure about the bindung. Where do i have to change it? Which file?

@pkulchenko
Copy link
Owner

Which functionality is not supported? If you want to add something that is already in wxWidgets, then you'd need to update one of the interface files (check *.i files in wxLua/bindings/wxWidgets folder) and then regenerate the bindings (by running genwxbind scripts). If you want to make something on your own in C++, then you'd need to figure out how to provide the necessary type information, but it seems like there is an easier way. wxWindow has GetHandle() method, which you can use to get the HWND value, which you can then use in your function to do whatever you want.

@Abooow786
Copy link
Author

Thanks for your help. I still could not do it. So i just wrote some new functions and included them to the wx.dll which later will be used by lua.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants