Obtaining vgui::Panel from a Lua Panel object

I’ve been trying, unsuccessfully, to get the vgui::Panel from Lua.
I’ve seen in gmcl_extras that you could obtain a vgui::VPANEL, which is a simple unsigned int, available to all modules, since there can be differences in the vtables (that’s what vgui::IPanel::GetPanel says).

I need to know how to do this, because I wanted to add some methods to DTextEntry, like SetWrap or SetFont.

Casting the user data to vgui::Panel from the Lua Panel object and using any of its methods crashes the game.

Casting it to vgui::VPANEL and then introducing it in vgui::IPanel::GetPanel works but it doesn’t return a TextEntry. It’s either the base GMod panel or an editable panel. Trying to get any of their children through vgui::IPanel::GetChild crashes the game.

Using the vgui::Panel returned by vgui::IPanel::GetPanel and obtaining it’s children through it doesn’t crash the game but the values are NULL.

I have even tried using the sigscanned function Get_Panel which should receive a integer for the stack position. Crashes as well.
I have extracted the classes Garry is using for his panels. They have slight differences but they have the same effect. Crashes the game.

Any help is appreciated.

I’ve experimented with trying to get a vgui panel from Lua myself and would like to possibly hear an answer from garry. I’ve ran into the same problems as you described with crashes in either vgui2.dll or MenuSystem.dll.

I found this on garrys blog awhile ago and it seems garry has a ILuaObject->ToPanel() which will, presumably, convert it to a vgui::Panel properly.

He uses networked string tables to get the loadingurl, look at GModGameInfo table.

As their name suggests, they’re just strings. The solution is not there.
On another note, that toPanel method must have been removed or it was an example because it doesn’t appear anywhere.
However, what is used in EVERY vgui (library) function and the vgui metamethods is Get_Panel(int a1). This functions seems to call some functions from CVProfile like EnterScope and ExitScope. But what is interesting here is the call to CLuaClass::Get(&LC_Panel, a1). a1 seems to be an integer, for example the stack position of the panel, since everytime Get_Panel is called, a1 is either 1 or 2 (2 is used in vgui.Create for example).
Get_Panel exists in the client and the menusystem binaries.

EDIT: Argh, it seems we’re all looking in the wrong place. Those vgui classes I said Garry was using would call functions of _g_pVGuiPanel, which is a global vgui::IPanel that can be initialized using those ConnectTierXLibraries. So, the userdata we get from the the Lua Panel object would be a vgui::VPANEL. Now, why I don’t get the panel I want but its parent, (it could be something else, I’m not sure) I don’t know. Needs more testing.

It looks like the CLuaClass::Get function returns a pointer to the userdata (which I think is vgui::Panel *), so you have dereference it.

Here’s the code I used to test:

[cpp]#include “GMLuaModule.h”

#include <vgui_controls/Panel.h>
#include <vgui_controls/HTML.h>

GMOD_MODULE( Open, Close );

LUA_FUNCTION( OpenURL_Test )
{
Lua()->CheckType( 1, GLua::TYPE_PANEL );
Lua()->CheckType( 2, GLua::TYPE_STRING );

vgui::Panel *pPanel = *(vgui::Panel **)Lua()-&gt;GetUserData( 1 );

if ( pPanel )
{
	Msg( "pPanel-&gt;GetName()=%s

", pPanel->GetName() );
Msg( "pPanel->GetClassName()=%s
", pPanel->GetClassName() );

	vgui::HTML *pHTML = dynamic_cast&lt;vgui::HTML *&gt;( pPanel );

	Msg( "pHTML=%p

", pHTML );

	if ( pHTML )
	{
		const char *url = Lua()-&gt;GetString( 2 );

		__asm
		{
			PUSH 0
			PUSH 0
			PUSH url
			MOV ECX, pHTML
			MOV EDX, [ECX]
			MOV EAX, [EDX+0x35C]
			CALL EAX
		}
	}
}

return 0;

}

int Open( lua_State *L )
{
ILuaObject *pPanelMetaTable = Lua()->GetMetaTable( “Panel”, GLua::TYPE_PANEL );

if ( pPanelMetaTable )
{
	pPanelMetaTable-&gt;SetMember( "OpenURL_Test", OpenURL_Test );
	pPanelMetaTable-&gt;UnReference();
}

return 0;

}

int Close( lua_State *L )
{
return 0;
}[/cpp]

The inline assembly was just because I couldn’t be bothered to update the HTML class.

That just made my day. Thanks. It seems that SetFont is crashing. Is it because I’m using VALVe’s class and not Garry’s one?

EDIT: Disregard this. The font I was getting was 0 and that was causing the crash.

EDIT2: Scratch that. Even after fixing that NULL font, it still crashes so I suppose it’s the classes.

Most of the VGUI control classes in the SDK are out of date, so yeah.

http://agent47.square7.ch/files/GModVGUIPanel.h
http://agent47.square7.ch/files/GModVGUITextEntry.h

This is what I have so far. I noticed that you used 0x35C as an offset for the function OpenURL (I suppose) while to me (http://agent47.square7.ch/files/vgui_HTML.h) it would be 0x368.
There’s something wrong in those headers. Also notice the 2 destructors in GModVGUIPanel or whatever they are.
Correct me if I’m wrong.

0x368 is the offset for OpenURL in the Mac binaries, which I’m guessing you are using. The difference is probably caused by some #ifdef’d virtual functions that are included in the Mac build but not the Windows build.

Oh right. Damn, I forgot about that. My bad.
Also, I’m not actually using the Mac binaries but just decompiled them.