Page 1 of 1
Help with DLLCall function (ImGui wrapper)
Posted: 25 Sep 2021, 12:12
by Noblish
Hello, i'm here because i've tried so much (1+ weeks) and I just don't understand how to pass it to DLLCall. I would really appreciate if someone explains it to me.
Code: Select all
Func _ImGui_CheckBox($text, ByRef $active)
Local $b_active = DllStructCreate("boolean value;")
$b_active.value = $active
Local $result = DllCall($IMGUI_DLL, "boolean:cdecl", "Checkbox", "wstr", $text, "ptr", DllStructGetPtr($b_active))
If @error Then Return SetError(1, 0, 0)
$active = $b_active.value
Return $result[0]
EndFunc
I know I have to mess with VarSetCapacity and NumGet/Numput. Or simpler, use a library…which I found some, but could not get it to work.
Btw I'm converting Imgui(c++) to ahk, it's nearly done, I'm just stuck with some functions.
It's a checkbox on Imgui, which will toggle a variable, ByRef $active refers to -> (b_show_demo_window = 1/0) (example)
please help me out
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 03:40
by just me
Just a guess:
Code: Select all
B_Active := !!Active ; converts the contents of Active to 0/1
Result := DllCall(IMGUI_DLL . "\Checkbox", "WStr", Text, "UCharP", B_Active, "Cdecl UChar")
MsgBox, %Result% - %Active% - %B_Active%
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 09:07
by Noblish
just me wrote: ↑26 Sep 2021, 03:40
Just a guess:
Code: Select all
B_Active := !!Active ; converts the contents of Active to 0/1
Result := DllCall(IMGUI_DLL . "\Checkbox", "WStr", Text, "UCharP", B_Active, "Cdecl UChar")
MsgBox, %Result% - %Active% - %B_Active%
Thanks for the reply , but it doesnt work
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 09:15
by swagfag
then post the c++ function prototype
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 09:19
by Noblish
swagfag wrote: ↑26 Sep 2021, 09:15
then post the c++ function prototype
Code: Select all
bool ImGui::Checkbox(const char* label, bool* v)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 label_size = CalcTextSize(label, NULL, true);
const float square_sz = GetFrameHeight();
const ImVec2 pos = window->DC.CursorPos;
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
ItemSize(total_bb, style.FramePadding.y);
if (!ItemAdd(total_bb, id))
return false;
bool hovered, held;
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
if (pressed)
{
*v = !(*v);
MarkItemEdited(id);
}
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
RenderNavHighlight(total_bb, id);
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
ImU32 check_col = GetColorU32(ImGuiCol_CheckMark);
if (window->DC.ItemFlags & ImGuiItemFlags_MixedValue)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
}
else if (*v)
{
const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f));
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
}
if (g.LogEnabled)
LogRenderedText(&total_bb.Min, *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f)
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed;
}
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 09:28
by swagfag
const char* is an AStr
and what is ImGui::? a class or a namespace?
and what is the calling convention?
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 10:05
by Noblish
C++ struct:
Ahk struct:
Code: Select all
VarSetCapacity(struct, 4, 0)
value := NumGet(struct, 0, "Int")
NumPut(value, struct, 0, "Int")
My approach.. :
Code: Select all
CheckBox(text, ByRef active){
VarSetCapacity(struct, 4, 0)
value := NumGet(struct, "Int")
Result := DllCall("imgui\Checkbox", "WStr", value, "Ptr", &active, "Cdecl Int")
active := active
Return result
}
I'm not sure if looking into c++ code rn is the right thing to do. I know I'm forgetting something , but I don't know what. I'm not an expert with structures or DllCall
Here my GitHub repo for this project:
https://github.com/Noblishh/imguiahk
Re: Help translate a code from AutoIT to AHK
Posted: 26 Sep 2021, 10:27
by swagfag
Noblish wrote: ↑26 Sep 2021, 10:05
I'm not sure if looking into c++ code rn is the right thing to do.
how else would u know what
DllCall types ure supposed to use?
Code: Select all
CheckBox(text, ByRef active){
VarSetCapacity(struct, 4, 0)
value := NumGet(struct, "Int")
Result := DllCall("imgui\Checkbox", "WStr", value, "Ptr", &active, "Cdecl Int")
active := active
Return result
}
i cant even begin to imagine what u intended to write with this function.
- text is an unused local param
- u allocate and zero-init 4 bytes
- u then cast that to an Int(which is of course 0)
- u then pass that 0(value) to the WStr param(which if we assume the function prototype u showed previously is correct, should have been an AStr)
- a Ptr-sized outparam is used for the bool*(wrong)
- its still unclear if the calling convention is __cdecl(no dll source and no info on what project settings were used to compile it)
- Int return type is used for a bool(wrong)
- active := active, ????
- based on the function prototype, its still unclear if ure trying to invoke a free function(in which case ImGUI:: will have been a namespace; possible) or an instance method(in which case ImGUI:: will have been a classname; impossible)
Re: Help with DLLCall function (ImGui wrapper)
Posted: 26 Sep 2021, 14:42
by Noblish
Main script Gui Loop:
Code: Select all
b_show_demo_window = false
;//------------------------------------------------------------------
While 1
{
ImGui.BeginFrame()
If Not ImGui.Begin("Test", True) Then Exit
;ImGui.ShowDemoWindow()
If ImGui.CheckBox("Show demo window", b_show_demo_window) Then ImGui.EnableViewports(b_show_demo_window)
If b_show_demo_window Then ImGui.ShowDemoWindow()
ImGui.End()
ImGui.EndFrame()
}
Checkbox func:
Code: Select all
CheckBox(text, ByRef active){
VarSetCapacity(struct, 4, 0)
value := NumGet(struct, 0, "Int")
Result := DllCall("imgui\Checkbox", "WStr", text, "Ptr", WHATtoINSERThere???, "Cdecl Int") ; "boolean:cdecl"
Return result
}
Yea, I know that I used *value* in the *text* zone, it meant for debug.
Bool translates to Int on AHK, you can't use *bool*.
Checkbox starts as default 0, whenever you click it turns to 1, that's how I open Other Gui's or toggle something. I just don't understand how to work out with "VarSetCapacity/NumGet/NumPut"
Re: Help with DLLCall function (ImGui wrapper)
Posted: 26 Sep 2021, 14:55
by swagfag
https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-160#sizes-of-built-in-types
no,
bool is
bool - ahk
UChar
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
typedef int BOOL; is
int - ahk
Int
Code: Select all
Result := DllCall("imgui\Checkbox", "AStr", text, "UChar*", &active, "Cdecl UChar") ; "boolean:cdecl"
whereby
active is a
variable with
1 or
0 already assigned to it
if that doesnt work,
__cdecl may be the wrong calling convention
Re: Help with DLLCall function (ImGui wrapper)
Posted: 27 Sep 2021, 03:14
by teadrinker
Must be
DllCall("imgui\Checkbox", "WStr", "My Checkbox", "UIntP", state, "Cdecl")
In the loop should look like this:
Code: Select all
currentState := newState := 1
while DllCall("imgui\PeekMsg", "Cdecl") {
...
if DllCall("imgui\Checkbox", "WStr", "My Checkbox", "UIntP", newState, "Cdecl")
currentState := newState := !currentState
...
}
Re: Help with DLLCall function (ImGui wrapper)
Posted: 27 Sep 2021, 12:25
by Noblish
teadrinker wrote: ↑27 Sep 2021, 03:14
Must be
DllCall("imgui\Checkbox", "WStr", "My Checkbox", "UIntP", state, "Cdecl")
In the loop should look like this:
Code: Select all
currentState := newState := 1
while DllCall("imgui\PeekMsg", "Cdecl") {
...
if DllCall("imgui\Checkbox", "WStr", "My Checkbox", "UIntP", newState, "Cdecl")
currentState := newState := !currentState
...
}
Sorry, but it doesn't work, I'm out of ideas :/
Re: Help with DLLCall function (ImGui wrapper)
Posted: 27 Sep 2021, 12:53
by teadrinker
Code: Select all
if !hLib := DllCall("LoadLibrary", "Str", "imgui.dll", "Ptr")
throw "Failed to load imgui.dll. Error: " . A_LastError
hWnd := DllCall("imgui\GUICreate", "WStr", "My Gui", "Int", 500, "Int", 400, "Int", 500, "Int", 200, "Cdecl Ptr")
WinShow, ahk_id %hWnd%
currentState := newState := 1
while DllCall("imgui\PeekMsg", "Cdecl") {
DllCall("imgui\BeginFrame", "Cdecl")
DllCall("imgui\Begin", "WStr", "New Window", "Int", 0, "Int", 0, "Cdecl")
if DllCall("imgui\Checkbox", "WStr", " My Checkbox", "UIntP", newState, "Cdecl")
currentState := newState := !currentState
DllCall("imgui\End", "Cdecl")
DllCall("imgui\EndFrame", "UInt", 0x004488, "Cdecl")
Sleep, 10
}
DllCall("FreeLibrary", "Ptr", hLib)
For me it works.
Re: Help with DLLCall function (ImGui wrapper)
Posted: 27 Sep 2021, 16:18
by Noblish
teadrinker wrote: ↑27 Sep 2021, 12:53
Code: Select all
if !hLib := DllCall("LoadLibrary", "Str", "imgui.dll", "Ptr")
throw "Failed to load imgui.dll. Error: " . A_LastError
hWnd := DllCall("imgui\GUICreate", "WStr", "My Gui", "Int", 500, "Int", 400, "Int", 500, "Int", 200, "Cdecl Ptr")
WinShow, ahk_id %hWnd%
currentState := newState := 1
while DllCall("imgui\PeekMsg", "Cdecl") {
DllCall("imgui\BeginFrame", "Cdecl")
DllCall("imgui\Begin", "WStr", "New Window", "Int", 0, "Int", 0, "Cdecl")
if DllCall("imgui\Checkbox", "WStr", " My Checkbox", "UIntP", newState, "Cdecl")
currentState := newState := !currentState
DllCall("imgui\End", "Cdecl")
DllCall("imgui\EndFrame", "UInt", 0x004488, "Cdecl")
Sleep, 10
}
DllCall("FreeLibrary", "Ptr", hLib)
For me it works.
Thanks man, appreciate.
Could you tell me why this function doesn't work ? I'm trying directing calling it
Code: Select all
CheckBox(text){
currentState := newState := 0
if DllCall("imgui\Checkbox", "WStr", text, "UIntP", newState, "Cdecl")
currentState := newState := !currentState
}
Re: Help with DLLCall function (ImGui wrapper)
Posted: 27 Sep 2021, 16:59
by teadrinker
Noblish wrote: ↑why this function doesn't work ?
It doesn't make any sense.
imgui::Checkbox can only work in the way I provided.
Re: Help with DLLCall function (ImGui wrapper) Topic is solved
Posted: 27 Sep 2021, 17:48
by teadrinker
This variant will work:
Code: Select all
if !hLib := DllCall("LoadLibrary", "Str", "imgui.dll", "Ptr")
throw "Failed to load imgui.dll. Error: " . A_LastError
hWnd := DllCall("imgui\GUICreate", "WStr", "My Gui", "Int", 500, "Int", 400, "Int", 500, "Int", 200, "Cdecl Ptr")
WinShow, ahk_id %hWnd%
while DllCall("imgui\PeekMsg", "Cdecl") {
DllCall("imgui\BeginFrame", "Cdecl")
DllCall("imgui\Begin", "WStr", "New Window", "Int", 0, "Int", 0, "Cdecl")
state1 := Checkbox(" My Checkbox", 0)
state2 := Checkbox(" Another Checkbox", 1)
DllCall("imgui\End", "Cdecl")
DllCall("imgui\EndFrame", "UInt", 0x004488, "Cdecl")
Sleep, 10
}
DllCall("FreeLibrary", "Ptr", hLib)
Checkbox(text, initialState := 0) {
static state := {}
if !state.HasKey(text)
state[text] := [initialState, initialState]
s := state[text]
if DllCall("imgui\Checkbox", "WStr", text, "UIntP", s[1], "Cdecl")
s[1] := s[2] := !s[2]
Return s[1]
}
Re: Help with DLLCall function (ImGui wrapper)
Posted: 28 Sep 2021, 08:44
by Noblish
teadrinker wrote: ↑27 Sep 2021, 17:48
This variant will work:
Code: Select all
if !hLib := DllCall("LoadLibrary", "Str", "imgui.dll", "Ptr")
throw "Failed to load imgui.dll. Error: " . A_LastError
hWnd := DllCall("imgui\GUICreate", "WStr", "My Gui", "Int", 500, "Int", 400, "Int", 500, "Int", 200, "Cdecl Ptr")
WinShow, ahk_id %hWnd%
while DllCall("imgui\PeekMsg", "Cdecl") {
DllCall("imgui\BeginFrame", "Cdecl")
DllCall("imgui\Begin", "WStr", "New Window", "Int", 0, "Int", 0, "Cdecl")
state1 := Checkbox(" My Checkbox", 0)
state2 := Checkbox(" Another Checkbox", 1)
DllCall("imgui\End", "Cdecl")
DllCall("imgui\EndFrame", "UInt", 0x004488, "Cdecl")
Sleep, 10
}
DllCall("FreeLibrary", "Ptr", hLib)
Checkbox(text, initialState := 0) {
static state := {}
if !state.HasKey(text)
state[text] := [initialState, initialState]
s := state[text]
if DllCall("imgui\Checkbox", "WStr", text, "UIntP", s[1], "Cdecl")
s[1] := s[2] := !s[2]
Return s[1]
}
Thank you really much for your idea, works perfectly!
Do you know why we can't close the GUI? Whenever I press the X button nothing happens, it doesn't go to the End() func. If I need to stop the loop, how I do so?
Re: Help with DLLCall function (ImGui wrapper)
Posted: 28 Sep 2021, 09:21
by teadrinker
For me my code breaks the loop. When I press the close button on GUI, DllCall("imgui\PeekMsg", "Cdecl") returns 0 and the cycle breaks, and the script terminates. Are you sure you launch my code as it is?
Re: Help with DLLCall function (ImGui wrapper)
Posted: 29 Sep 2021, 11:52
by Noblish
teadrinker wrote: ↑28 Sep 2021, 09:21
For me my code breaks the loop. When I press the close button on GUI,
DllCall("imgui\PeekMsg", "Cdecl") returns
0 and the cycle breaks, and the script terminates. Are you sure you launch my code as it is?
Yes it breaks the loop, but i mean click on the X on imgui, not ahk gui. Also , im not drawing with the gui. I could also just hide it , but the correct way is just to break the drawing loop and quit the current gui. im not sure if the error is coming from ImGui.Begin or ImGui.GUICreate. Or if i simply need to make some if states
Re: Help with DLLCall function (ImGui wrapper)
Posted: 29 Sep 2021, 13:16
by teadrinker
Noblish wrote: ↑i mean click on the X on imgui, not ahk gui. Also , im not drawing with the gui.
I'm not sure I understand what you mean. GUI in my code is created by imgui, there is not any AHK GUI.
If you showed your code it would make things clearer.