Fred
Here is my 6 Kb VS2019 Mini version using TCLib.
This is the same code i am using with all the programming languages from my soap box.
VS 2019 version
#include <windows.h>
constexpr auto CLIENT_WIDTH = 640;
constexpr auto CLIENT_HEIGHT = 480;
struct PROP {
HWND hMain;
long minTrackSizeW;
long minTrackSizeH;
};
static PROP gP;
long Width(IN RECT &r) {
return r.right - r.left;
}
long Height(IN RECT &r) {
return r.bottom - r.top;
}
LRESULT CALLBACK WndProc(IN HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) {
LRESULT nRet = -1;
MINMAXINFO* pMM;
switch (uMsg) {
case WM_CREATE:
break;
case WM_GETMINMAXINFO:
pMM = (MINMAXINFO*)lParam;
pMM->ptMinTrackSize.x = gP.minTrackSizeW;
pMM->ptMinTrackSize.y = gP.minTrackSizeH;
break;
case WM_SIZE:
InvalidateRect(hWnd, NULL, TRUE);
nRet = 0;
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
// Paint the window content here
EndPaint(hWnd, &ps);
nRet = 0;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
nRet = 0;
break;
}
if (nRet == -1) nRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
return nRet;
}
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
int nRet = 0;
WCHAR szClass[] = L"MINI";
// Detect process without using a Mutex
HWND hFound = FindWindow(szClass, NULL);
if (hFound) {
if (IsIconic(hFound)) { ShowWindow(hFound, SW_RESTORE); }
SetForegroundWindow(hFound);
return nRet;
}
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(wcx);
long IsInitialized = GetClassInfoEx(hInstance, szClass, &wcx);
if (!IsInitialized) {
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
wcx.lpszMenuName = 0;
wcx.lpszClassName = szClass;
wcx.hIconSm = wcx.hIcon;
if (RegisterClassEx(&wcx)) { IsInitialized = -1; }
}
if (IsInitialized) {
DWORD dwExStyle = 0;
DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
RECT lpr = { 0 }; SetRect(&lpr, 0, 0, CLIENT_WIDTH, CLIENT_HEIGHT);
AdjustWindowRectEx(&lpr, dwStyle, FALSE, dwExStyle);
gP.minTrackSizeW = Width(lpr);
gP.minTrackSizeH = Height(lpr);
long x = max((GetSystemMetrics(SM_CXSCREEN) - gP.minTrackSizeW) / 2, 0);
long y = max((GetSystemMetrics(SM_CYSCREEN) - gP.minTrackSizeH) / 2, 0);
gP.hMain = CreateWindowEx(dwExStyle, szClass, szClass, dwStyle, x, y, gP.minTrackSizeW, gP.minTrackSizeH, 0, 0, hInstance, NULL);
if (gP.hMain) {
ShowWindow(gP.hMain, nCmdShow);
SetForegroundWindow(gP.hMain); // Slightly Higher Priority
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
nRet = (int) msg.wParam;
}
UnregisterClass(wcx.lpszClassName, hInstance);
}
return nRet;
}
WinDev version
//+--------------------------------------------------------------------------+
//| MINI |
//| |
//| Create an empty SDI SDK popup window |
//| |
//+--------------------------------------------------------------------------+
//| Author Patrice TERRIER |
//| copyright(c) 2014 |
//| www.zapsolution.com |
//| pterrier@zapsolution.com |
//+--------------------------------------------------------------------------+
CONSTANT
ClientW = 640
ClientH = 480
END
PROP is Structure
hMain is system int
MinTrackSizeW is int
MinTrackSizeH is int
END
gP is PROP // Global class properties
// This is the main entry code (but with with WinDev the main entry code is always in the "project code")
// C'est le point d'entrée du programme (mais avec WinDev le point d'entrée principal est le "code du projet")
FUNCTION MainWindow()
wcx is WNDCLASSEXA
szClass is string ASCIIZ on 16 = "FLAT_API_POPUP" // The class name of our popup window.
wcx.cbSize = Dimension(wcx)
IsInitialized is int = GetClassInfoExA(Instance, szClass, wcx)
IF IsInitialized = 0 THEN
wcx.style = CS_HREDRAW | CS_VREDRAW
wcx.lpfnWndProc = &WndProc
wcx.cbClsExtra = 0
wcx.cbWndExtra = 0 // Extend_cbWndExtra * 4
wcx.hInstance = Instance
wcx.hIcon = Null
wcx.hCursor = API(USER32, "LoadCursorA", Null, IDC_ARROW)
wcx.hbrBackground = GetStockObject(WHITE_BRUSH)
wcx.lpszMenuName = Null
wcx.lpszClassName = &szClass
wcx.hIconSm = Null
IF RegisterClassExA(wcx) THEN IsInitialized = True
END
IF IsInitialized THEN
nRet is unsigned int = 0
r is RECT
uMsg is TagMSG
dwExStyle is unsigned int = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE
dwStyle is unsigned int = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
SetRect(r, 0, 0, ClientW, ClientH)
AdjustWindowRectEx(r, dwStyle, False, dwExStyle)
gP.MinTrackSizeW = r.nRight - r.nleft
gP.MinTrackSizeH = r.nBottom - r.nTop
x is int = Max((GetSystemMetrics(SM_CXSCREEN) - gP.MinTrackSizeW) / 2, 0)
y is int = Max((GetSystemMetrics(SM_CYSCREEN) - gP.MinTrackSizeH) / 2, 0)
sCaption is string = "Popup window "
IF In64bitMode() THEN sCaption += "64-bit" ELSE sCaption += "32-bit"
gP.hMain = CreateWindowExA(0, szClass, sCaption, dwStyle, x, y, gP.MinTrackSizeW, gP.MinTrackSizeH, 0, 0, Instance, 0)
IF gP.hMain THEN
ShowWindow(gP.hMain, SW_SHOW)
SetForegroundWindow(gP.hMain) // Slightly Higher Priority
// Main message pump.
WHILE GetMessageA(uMsg, Null, 0, 0)
TranslateMessage(uMsg)
DispatchMessageA(uMsg)
END
nRet =uMsg.wParam
END
END
RESULT nRet
// WinMain callback function.
// Function callback utilisée par la fenêtre principale.
FUNCTION WndProc(LOCAL hWnd is system int, LOCAL uMsg is unsigned int, LOCAL wParam is unsigned int, LOCAL lParam is system int)
ps is PAINTSTRUCT;
nRet is int = -1; // -1 means let Windows perform the default message processing
hDC is system int;
SWITCH uMsg
CASE WM_GETMINMAXINFO:
pMM is MINMAXINFO
Transfer(&pMM, lParam, Dimension(pMM));
pMM.ptMinTrackSize.x = gP.MinTrackSizeW;
pMM.ptMinTrackSize.y = gP.MinTrackSizeH;
Transfer(lParam, &pMM, Dimension(pMM));
CASE WM_SIZE
InvalidateRect(hWnd, Null, True);
nRet = 0;
CASE WM_COMMAND
wmId is int = LOINT(wParam);
wmEvent is int = HIINT(wParam);
// SWITCH (wmId)
//
// END
nRet = 0;
CASE WM_PAINT
hDC = BeginPaint(hWnd, ps);
// Paint the window content here
EndPaint(hWnd, ps);
nRet = 0;
CASE WM_DESTROY
PostQuitMessage(0);
nRet = 0;
OTHER CASE
END
IF nRet = -1 THEN
nRet = DefWindowProcA(hWnd, uMsg, wParam, lParam);
END
RESULT nRet;