-2

I'm currently trying to make pure WinAPI calculator that will have:

  • 1 result textbox (where all data would be displayed)
  • some buttons like plus, minus, 1, 2 etc (on click, these will append text like 1,+,2 etc to Result textbox)

So now, suppose the result textbox contains string like 1 + 1, 7 / 2, 2 * 2, 8 - 8 etc, How can I invoke these strings to return data like 2, 3.5, 4, 0 respectively?

Is there any standard api in WinAPI by which I can invoke the calculation inside a string? Or do I need to make my own?

I'm using C WinAPI. And here I got manage to complete UI and append text via buttons. Please see code:

#include <windows.h>
int IDC_result = 16;
int w = 50;
int h = 50; 

void DrawButton(HWND hwnd, const char* Text, int x, int y, int code)
{
    CreateWindowW(TEXT("button"), (LPCWSTR)Text, WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, x, y, w, h, hwnd, (HMENU)code, NULL, NULL);
}
 
const char* texts[] = 
{
    "7","8","9","/",
    "4","5","6","*",
    "1","2","3","-",
    "0",".","=","+"
};
int textsLenght = (int)(sizeof(texts) / sizeof(texts[0]));

HWND RESULTS;
void DrawControls(HWND hwnd)
{
    int TotalColms = 4;
    RESULTS = CreateWindowEx(WS_EX_TRANSPARENT, TEXT("Edit"), TEXT(""), WS_CHILD | WS_VISIBLE | SS_LEFT | WS_SYSMENU, w * 1, h - 25, w * TotalColms, h - 30, hwnd, (HMENU)IDC_result, NULL, NULL);
    int colm = 1;
    int row = 1;
    for(int text = 0; text < textsLenght; text++)
    {
        DrawButton(hwnd,texts[text],w * colm,h * row,text);
        if (textsLenght / colm == TotalColms)
        {
            colm = 0;
            row++;
        }
        colm++;
    }
}

void appendText(LPARAM Text)
{
    int Lenght = GetWindowTextLength(RESULTS);
    SendMessageW(RESULTS, EM_SETSEL, Lenght, Lenght);
    SendMessageW(RESULTS, EM_REPLACESEL, TRUE, Text);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
            DrawControls(hwnd);
            break;
        case WM_COMMAND:
        {
            int no = LOWORD(wParam);
            if (no > -1 && no < textsLenght)
            {
                appendText((LPARAM)texts[no]);
            }
            break;
        }
        case WM_DESTROY: PostQuitMessage(0);
        default: return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    WNDCLASS wc;
    HWND hwnd;
    ZeroMemory(&wc, sizeof wc);
    wc.hInstance = hInstance;
    wc.lpszClassName = L"Calculator";
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    if (FALSE == RegisterClass(&wc)) return 0;
    hwnd = CreateWindowW(
        L"Calculator",L"Calculator"
        ,WS_OVERLAPPEDWINDOW | WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,
        300,500
        ,0,0,hInstance,0);
    if (NULL == hwnd) return 0;
    while (GetMessage(&msg, NULL, 0, 0) > 0) 
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

enter image description here

Please comment, if anything unclear.

Patricio
  • 60
  • 9
Gray Programmerz
  • 479
  • 1
  • 5
  • 22

1 Answers1

1

Is there any standard api in winapi by which we can invoke the calculation inside a string ? or I need to make my own ?

No there is no standard API for this; you must either make your own, or more practically find a pre-made library for this.

Another option if you want something that "just works even though it's extremely dirty/hacky/insecure" is to find a way to invoke powershell from your app and capture the output.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • Example library: https://github.com/zserge/expr – fpiette Jun 28 '21 at 16:04
  • "find a way to invoke powershell from your app and capture the output." While this is a technically correct answer to OP's question. invoking a shell with user-provided content is a security minefield in the best of scenarios. OP should **not** use this approach under any circumstance here. –  Jun 28 '21 at 16:07
  • @fra What sort of *"security minefield"* do you have in mind? Are you sure you understand how [access control](https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control) works in Windows? – IInspectable Jun 28 '21 at 18:18
  • I think in most reasonable cases there would be no security risk (though I guess we could all contrive scenarios where this would be a problem where it doesn't feel like there should be one). But it's definitely a bad solution in the sense that to do it reliably & correctly you'll spend more effort than just using a proper library. It's a simple-looking solution that's actually very complex. – tenfour Jun 28 '21 at 18:33