Help with DLLCall function (ImGui wrapper) Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Help with DLLCall function (ImGui wrapper)

25 Sep 2021, 12:12

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)

Image

please help me out :)
Last edited by Noblish on 26 Sep 2021, 10:08, edited 1 time in total.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Help translate a code from AutoIT to AHK

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%
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help translate a code from AutoIT to AHK

26 Sep 2021, 09:07

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
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Help translate a code from AutoIT to AHK

26 Sep 2021, 09:15

then post the c++ function prototype
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help translate a code from AutoIT to AHK

26 Sep 2021, 09:19

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;
}
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Help translate a code from AutoIT to AHK

26 Sep 2021, 09:28

const char* is an AStr
and what is ImGui::? a class or a namespace?
and what is the calling convention?
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help translate a code from AutoIT to AHK

26 Sep 2021, 10:05

C++ struct:

Code: Select all

typedef checkbox {
	int value;
	} ;
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
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Help translate a code from AutoIT to AHK

26 Sep 2021, 10:27

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)
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help with DLLCall function (ImGui wrapper)

26 Sep 2021, 14:42

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"
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Help with DLLCall function (ImGui wrapper)

26 Sep 2021, 14:55

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
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Help with DLLCall function (ImGui wrapper)

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
   ...
}
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help with DLLCall function (ImGui wrapper)

27 Sep 2021, 12:25

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 :/
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Help with DLLCall function (ImGui wrapper)

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.
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help with DLLCall function (ImGui wrapper)

27 Sep 2021, 16:18

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
    }
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Help with DLLCall function (ImGui wrapper)

27 Sep 2021, 16:59

Noblish wrote: why this function doesn't work ?
It doesn't make any sense. imgui::Checkbox can only work in the way I provided.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Help with DLLCall function (ImGui wrapper)  Topic is solved

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]
}
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help with DLLCall function (ImGui wrapper)

28 Sep 2021, 08:44

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?
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Help with DLLCall function (ImGui wrapper)

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?
Noblish
Posts: 28
Joined: 22 Mar 2020, 06:10

Re: Help with DLLCall function (ImGui wrapper)

29 Sep 2021, 11:52

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
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Help with DLLCall function (ImGui wrapper)

29 Sep 2021, 13:16

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.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: JoeWinograd and 179 guests