So I found the solution to that very, very niche problem of not being able to pass any parameter with delegates in a custom UUserWidget class. It’s not pretty (be warned) but it works and might avoid rewriting everything into Slate when so much is already written in UMG, for now.
So because apparently us dums dums aren’t to access the underlying SButton of a UButton at any cost, the SButton* MyButton property is “protected.” You can unprotect it and enjoy lengthy recompilations or call your old friend C to the rescue. But he doesn’t come. Because pointers to members are C++, and unsafe casting-deferencing to pointers to members isn’t allowed.
A pointer to member is a 32 bit integer. Knowing that the SButton* is in the last row of UButton’s binary layout, you can write in a namespace (be warned again) :
inline SButton* UButton::* UButton_internal = []() { SButton* UButton::* ptr; uint32 INCREM = sizeof(UButton) - alignof(UButton); memcpy(&ptr, &INCREM, 4); return ptr; }();
Then you can use it to access the SButton with the syntax :
(Button->*MyNamespace::UButton_internal)->DoStuff();
Including passing parameters :
for (uint8 i = 0; i < Buttons.Num(); i++) {
FOnClicked onclicked; onclicked.BindLambda([this, i]() -> FReply { this->FunctionWithOneByteParameter(i); return FReply::Handled(); });
(Buttons[i]->*MyNamespace::UButton_internal)->SetOnClicked(onclicked);
}
It’s ugly but it works and it’s pretty much the only way to do it.