View Single Post
  #1  
Old 04-09-2020, 20:41
WhoCares's Avatar
WhoCares WhoCares is offline
who cares
 
Join Date: Jan 2002
Location: Here
Posts: 468
Rept. Given: 11
Rept. Rcvd 32 Times in 25 Posts
Thanks Given: 69
Thanks Rcvd at 247 Times in 94 Posts
WhoCares Reputation: 32
a good GUI framework for writing keygen: ImGui

For writing keygen, only limited types of widgets are needed, such as EditBox/Button/ComboBox/CheckBox etc.

Dear ImGui is a good GUI framework for writing keygen, with the concept of "Immediate Mode GUI", which is quite different from stateful GUI framework such as MFC/Qt etc. The generated EXE is less than 200KB with "Win32 + DirectX" binding and static CRT linking and /OPT:REF and /OPT:ICF. If you cut some source code manually, or use VC-LTL(https://github.com/Chuyu-Team/VC-LTL), EXE size can be decreased more.

It also has bindings for MacOS and Linux, which means you can also easily write small-size GUI keygen for MacOS and Linux, though different bindings require recompiling. If you want universal binding, SDL binding may be a choice, but the file size may increase.

github(we can play with its examples. The author of Dear ImGUI is quite active):
https://github.com/ocornut/imgui

some hints:

1. uncomment the following macros to cut gamepad support and directx xinput to decrease file size and remove xinput dll dependency.
Code:
#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
#define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT
2.disable "imgui.ini" saving/loading. or remove related code.
Code:
    ImGuiIO& io = ImGui::GetIO();
    io.IniFilename = NULL;
3. there are 3 built-in color styles, just choose one of them or add your own.
Code:
    //ImGui::StyleColorsDark();
    ImGui::StyleColorsClassic();
    //ImGui::StyleColorsLight();
4. load your own fonts.
Code:
    ImGuiIO& io = ImGui::GetIO();
    font = io.Fonts->AddFontFromFileTTF(u8"c:\\windows\\fonts\\cour.ttc", 16.0f * highDPIscaleFactor,...)
5. DPI scaling.

get DPI scaling factor "highDPIscaleFactor" for current desktop window, then multiply any height/width with this factor.
Code:
    ImGui_ImplWin32_EnableDpiAwareness();
    float highDPIscaleFactor = ImGui_ImplWin32_GetDpiScaleForHwnd(GetDesktopWindow());
set auto scaling when creating widgets without height/width specified:
Code:
    ImGuiStyle& style = ImGui::GetStyle();
    style.ScaleAllSizes(highDPIscaleFactor);
multiply the height/width of Win32 main window with highDPIscaleFactor:
Code:
HWND hwnd = ::CreateWindow(wc.lpszClassName, L"window demo title", WS_POPUPWINDOW, 0, 0, WINDOW_WIDTH * highDPIscaleFactor, WINDOW_HEIGHT * highDPIscaleFactor, NULL, NULL, wc.hInstance, NULL);
multiply the font size with highDPIscaleFactor:
Code:
    ImGuiIO& io = ImGui::GetIO();
    font = io.Fonts->AddFontFromFileTTF(u8"c:\\windows\\fonts\\cour.ttc", 16.0f * highDPIscaleFactor,...)
multiply the child window width with highDPIscaleFactor:
Code:
ImGui::BeginChild("Child", ImVec2(0, 90 * highDPIscaleFactor), true, window_flags);
I will not cover how to respond to DPI-changed message of Windows here, just add it by yourself if needed.

6. specify widget width with font size.

note: font size returned by ImGui::GetFontSize() is already DPI-scaled.
25.0 is the number of chars. If you use CJK font, the font width is double of English fonts, the width of 1 CJK char is that of 2 English chars.
Code:
ImGui::PushItemWidth((float)(int)(ImGui::GetFontSize() * 25.0f));
...
ImGui::PopItemWidth();
7. hide Win32 main window title bar, and drag window with window widget title bar(this part is for Win32 only)

A window widget is a kind of ImGui widgets whose type is "window".

hide win32 main window title:
just pass WS_POPUPWINDOW instead of WS_OVERLAPPEDWINDOW to CreateWindow.
Code:
HWND hwnd = ::CreateWindow(wc.lpszClassName, L"demo", WS_POPUPWINDOW, 0, 0, WINDOW_WIDTH * highDPIscaleFactor, WINDOW_HEIGHT * highDPIscaleFactor, NULL, NULL, wc.hInstance, NULL);
create a widget whose type is "window". A "close" button will apear in the title bar of this widget, but no minimize/maximize button supported yet. Fill all of its parent window(i.e. client area of Win32 main window) with this widget.
save the title bar height in a global variable for later use.
Code:
           static int titleBarHeight = 0;

            ImGui::SetNextWindowPos(ImVec2(0, 0));
            ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);

            bool windowStatus = true;
            ImGui::Begin(u8"demo window widget title", &windowStatus, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings);

            if (!titleBarHeight)
                titleBarHeight = ImGui::GetFrameHeight();
if user clicks the "close" button of this window widget, call PostQuitMessage:
Code:
            if (!windowStatus)
                ::PostQuitMessage(0);
in WndProc() of Win32 main window, check whether user is dragging the title bar of this window widget and move the title-less Win32 window accordingly.
Code:
static bool dragWindow = false;

// Win32 message handler
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
        return true;

    static POINT startPos;

    switch (msg)
    {
    case WM_LBUTTONDOWN:
        startPos.x = (int)(short)LOWORD(lParam);
        startPos.y = (int)(short)HIWORD(lParam);
        if (titleBarHeight > 0 && startPos.y <= titleBarHeight)
        {
            dragWindow = true;
            SetCapture(hWnd);
        }
        break;
    case WM_LBUTTONUP:
        if (dragWindow)
        {
            dragWindow = false;
            ReleaseCapture();
        }
        break;
    case WM_MOUSEMOVE:
        if (dragWindow && (wParam & MK_LBUTTON))
        {
            RECT mainWindowRect;
            POINT pos;
            int windowWidth, windowHeight;

            pos.x = (int)(short)LOWORD(lParam);
            pos.y = (int)(short)HIWORD(lParam);

            GetWindowRect(hWnd, &mainWindowRect);
            windowHeight = mainWindowRect.bottom - mainWindowRect.top;
            windowWidth = mainWindowRect.right - mainWindowRect.left;

            ClientToScreen(hWnd, &pos);
            MoveWindow(hWnd, pos.x - startPos.x, pos.y - startPos.y, windowWidth, windowHeight, TRUE);
        }
        break;
8. add keyboard support for widgets, such Ctrl + C to copy text.
Code:
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
A keygen template source code repo deserves many words, but currently no time to do it yet. If anyone would like to help, it will be nice.
__________________
AKA Solomon/blowfish.

Last edited by WhoCares; 04-09-2020 at 20:52.
Reply With Quote
The Following 5 Users Say Thank You to WhoCares For This Useful Post:
chants (04-10-2020), Doit (06-04-2020), sh3dow (12-07-2022), SinaDiR (04-11-2020), Stingered (04-10-2020)