There's a bit of confusion here... API stands for Application PROGRAM Interface and it is the same for both i386 and x86-64 modes on Windows. There's no Win64 API, just Win32 API. ABI stands for Application BINARY Interface and are different for i386 and x86-64.
x86-64 is the generic nomenclature for amd64 mode of operation of the processor (AMD nomenclature), or Intel 64 or IA-32e or the old EMT64 (3 of Intel's nomenclature), or x64 mode (Microsoft nomenclarure)... i386 mode is x86 (Microsoft) or IA-32 (Intel).
Take this simple program writen in C:
/* main.c */
#include <windows.h>
/* Protótipo do procedimento de janela */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR lpszCmdLine,
int nCmdShow)
{
const static LPCSTR szClassName = "SimpleAppClass";
HWND hWnd;
MSG msg;
WNDCLASS wc =
{
.style = CS_HREDRAW | CS_VREDRAW,
.lpfnWndProc = WndProc,
.hInstance = hInst,
.hIcon = LoadIcon(NULL, IDI_APPLICATION),
.hCursor = LoadCursor(NULL, IDC_ARROW),
.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1),
.lpszClassName = szClassName
};
RegisterClass(&wc);
/* Este estilo criará uma janela "normal" que não pode
ser maximizada ou ter seu tamanho alterado. */
#define WINDOW_STYLE WS_OVERLAPPED | \
WS_SYSMENU | \
WS_VISIBLE | \
WS_BORDER | \
WS_MINIMIZEBOX | \
WS_CAPTION
hWnd = CreateWindowEx( 0,
szClassName,
"My Simple App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
320, 100,
NULL, NULL,
hInst,
NULL );
if ( ! hWnd )
{
/* Trata erro se não conseguiu criar a janela. */
MessageBox( NULL,
"Erro ao tentar criar a janela da aplicação.",
"Erro",
MB_OK | MB_ICONERROR);
return 0;
}
UpdateWindow( hWnd );
ShowWindow( hWnd, SW_SHOW ); /* Sempre mostra! */
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam;
}
// winproc.c
#include <windows.h>
LRESULT CALLBACK WndProc( HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
{
PAINTSTRUCT ps;
RECT rc;
// Processa mensagens...
switch (uMsg)
{
// Ao destruir a janela...
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
GetClientRect( hWnd, &rc );
BeginPaint( hWnd, &ps );
DrawText( ps.hdc, "Hello, world!", -1, &rc, DT_CENTER | DT_VCENTER );
EndPaint( hWnd, &ps );
return 0;
}
// Trata todas as outras mensagens.
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
You can compile for 32 or 64 bits and it will work, unchanged, for Win95, Win98, WinMe, WinVista, WinXP, Win8, Win10 and Win11, in both 32 or 64 bits. This means the program interface is the same (Win32 API), but, of course the way stack is used, the arguments are passed to functions, registers used, etc, are different (MS-ABI for i386 or MS-ABI for x86-64).