app.dhover×230 error×51all
// F02 — resize correctness, Win32 (../../f02-resize.md).
//
// Implements every requirement of ../../../features/f02-resize.md on top of
// the scaffold (../scaffold/app.d):
//
//   * Continuously redrawn corner-anchored gradient (red tracks x, green
//     tracks y, blue advances per frame) so stretching or stale buffers are
//     visible; after every draw the buffer's four corners are verified
//     against the expected gradient values (`paint_check`).
//   * An aggressive programmatic SetWindowPos storm (WSI_AUTO_EXIT=1):
//     pure grows, pure shrinks, mixed grow/shrink, move-only (SWP_NOSIZE)
//     and a same-size no-move step — each followed by a synchronous
//     UpdateWindow and a `step_result painted=` verdict.
//   * Every WM_SIZING / WM_SIZE / WM_WINDOWPOSCHANGING / WM_WINDOWPOSCHANGED
//     / WM_ERASEBKGND / WM_PAINT is logged with its wParam / WINDOWPOS
//     fields / client size.
//   * WSI_NO_INVALIDATE=1 drops the per-step InvalidateRect, reproducing the
//     scaffold's "a pure shrink invalidates nothing" finding: shrink steps
//     then present no frame and the window keeps a stale, wrongly-anchored
//     gradient (step_result painted=0).
//   * WSI_GROW_ONLY=1 switches the DIB strategy from realloc-per-resize to
//     grow-only reuse (the DIB keeps its high-water-mark size; smaller client
//     sizes draw through a stride and log `buffer_reuse` instead of
//     `buffer_alloc`).
//   * WM_SIZING (and WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE) cannot fire from a
//     programmatic storm — their observed count is logged at storm end; the
//     interactive modal-resize path is F03's subject (Tier C here).
//
// Only druntime's built-in core.sys.windows bindings — no third-party packages.
module 
(module) app
app
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.windows
windows
.
(module) core.sys.windows.windows

Windows API header module

Translated from MinGW API for MS-Windows 4.0

Source

core/sys/windows/windows.d

windows
;
import instrument;
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
struct
(struct) app.Demo
Demo
{ HDC
(field) _error_ app.Demo.memDc
memDc
; // memory DC the DIB section is selected into
undefined identifier `HDC`
HBITMAP
(field) _error_ app.Demo.dib
dib
; // top-down 32-bit DIB section (CPU-visible backbuffer)
undefined identifier `HBITMAP`
HBITMAP
(field) _error_ app.Demo.stockBmp
stockBmp
; // the 1x1 stock bitmap displaced by SelectObject
undefined identifier `HBITMAP`
uint*
(field) uint* app.Demo.pixels
pixels
; // DIB bits: 0x00RRGGBB, row-major, row 0 = top row
int
(field) int app.Demo.width
width
,
(field) int app.Demo.height
height
; // current client size, physical pixels
int
(field) int app.Demo.capW
capW
,
(field) int app.Demo.capH
capH
; // allocated DIB size (== width/height unless grow-only)
int
(field) int app.Demo.dpi
dpi
= 96; // monitor DPI; scale = dpi / 96
uint
(field) uint app.Demo.frame
frame
; // paint counter (animates the gradient)
uint
(field) uint app.Demo.ticks
ticks
; // WM_TIMER counter (auto-exit schedule)
uint
(field) uint app.Demo.sizingCount
sizingCount
; // WM_SIZING messages seen (expected 0 programmatically)
uint
(field) uint app.Demo.sizeMoveCount
sizeMoveCount
; // WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE seen (expected 0)
uint
(field) uint app.Demo.checksFailed
checksFailed
; // paint_check corner mismatches
bool
(field) bool app.Demo.autoExit
autoExit
; // WSI_AUTO_EXIT=1: bounded run with the resize storm
bool
(field) bool app.Demo.noInvalidate
noInvalidate
; // WSI_NO_INVALIDATE=1: drop the per-step InvalidateRect
bool
(field) bool app.Demo.growOnly
growOnly
; // WSI_GROW_ONLY=1: grow-only DIB reuse instead of realloc
bool
(field) bool app.Demo.firstSizeSeen
firstSizeSeen
;
bool
(field) bool app.Demo.firstPaintDone
firstPaintDone
;
} __gshared
(struct) app.Demo
Demo
_error_ app.g
g
;
enum UINT_PTR
(constant) _error_ app.TIMER_ID = __error
TIMER_ID
= 1;
undefined identifier `UINT_PTR`
enum
(constant) int app.TICK_MS = 16
TICK_MS
= 16; // ~60 Hz animation tick
enum
(constant) int app.STORM_AFTER_TICKS = 30
STORM_AFTER_TICKS
= 30; // ~0.5 s of animation before the resize storm
// --------------------------------------------------------------------------- // Backbuffer. Two strategies (the allocation strategy is an F02 finding): // realloc (default): free + CreateDIBSection on every client-size change. // grow-only (WSI_GROW_ONLY=1): the DIB only ever grows (per-dimension // high-water mark); a smaller client size reuses it through a row stride. void
void app.createBackbuffer(int w, int h) nothrow
createBackbuffer
(int
(parameter) int w
w
, int
(parameter) int h
h
) nothrow
{ if (
(parameter) int w
w
<= 0 ||
(parameter) int h
h
<= 0)
{
void app.releaseBackbuffer() nothrow
releaseBackbuffer
();
return; } if (g.
(field) _error_ g.growOnly
growOnly
&& g.
(field) _error_ g.dib
dib
!is null &&
(parameter) int w
w
<= g.
(field) _error_ g.capW
capW
&&
(parameter) int h
h
<= g.
(field) _error_ g.capH
capH
)
{ g.
g.width
width
= w;
g.
g.height
height
= h;
logEvent("buffer_reuse size=%dx%d cap=%dx%d", w, h, g.
g.capW
capW
, g.
g.capH
capH
);
undefined identifier `logEvent`
return; } const
(local variable) const(_error_) allocW
allocW
= g.
(field) _error_ g.growOnly
growOnly
? (
(parameter) int w
w
> g.
(field) _error_ g.capW
capW
?
(parameter) int w
w
: g.
(field) _error_ g.capW
capW
) :
(parameter) int w
w
;
const
(local variable) const(_error_) allocH
allocH
= g.
(field) _error_ g.growOnly
growOnly
? (
(parameter) int h
h
> g.
(field) _error_ g.capH
capH
?
(parameter) int h
h
: g.
(field) _error_ g.capH
capH
) :
(parameter) int h
h
;
void app.releaseBackbuffer() nothrow
releaseBackbuffer
();
BITMAPINFO
(local variable) _error_ bmi
bmi
;
undefined identifier `BITMAPINFO`
bmi.bmiHeader.biSize = BITMAPINFOHEADER.sizeof; bmi.bmiHeader.biWidth = allocW; bmi.bmiHeader.biHeight = -allocH; // negative height = top-down rows bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; void*
(local variable) void* bits
bits
;
g.
g.dib
dib
= CreateDIBSection(null, &bmi, DIB_RGB_COLORS, &bits, null, 0);
if (g.
(field) _error_ g.dib
dib
is null)
{ logEvent("error what=CreateDIBSection code=%lu", GetLastError());
undefined identifier `logEvent`
return; } g.
g.pixels
pixels
= cast(uint*) bits;
g.
g.width
width
= w;
g.
g.height
height
= h;
g.
g.capW
capW
= allocW;
g.
g.capH
capH
= allocH;
g.
g.stockBmp
stockBmp
= cast(HBITMAP) SelectObject(g.
g.memDc
memDc
, g.
g.dib
dib
);
logEvent("buffer_alloc size=%dx%d cap=%dx%d bytes=%d",
undefined identifier `logEvent`
w, h, allocW, allocH, allocW * allocH * 4); } void
void app.releaseBackbuffer() nothrow
releaseBackbuffer
() nothrow
{ if (g.
(field) _error_ g.dib
dib
is null)
return; SelectObject(g.
g.memDc
memDc
, g.
g.stockBmp
stockBmp
);
undefined identifier `SelectObject`
DeleteObject(g.
g.dib
dib
);
undefined identifier `DeleteObject`
g.
g.dib
dib
= null;
g.
g.pixels
pixels
= null;
g.
g.width
width
= g.
g.height
height
= g.
g.capW
capW
= g.
g.capH
capH
= 0;
} // Corner-anchored diagonal gradient over the *current* client size, drawn // through the allocated stride (capW) so grow-only reuse stays anchored. void
void app.drawGradient() nothrow
drawGradient
() nothrow
{ if (g.
(field) _error_ g.pixels
pixels
is null)
return; const
(local variable) const(_error_) w
w
= g.
(field) _error_ g.width
width
,
(local variable) const(_error_) h
h
= g.
(field) _error_ g.height
height
;
const
(local variable) const(_error_) blue
blue
= (g.
(field) _error_ g.frame
frame
* 4) & 0xff;
foreach (
(parameter) y
y
; 0 .. h)
{ uint*
_error_ row
row
= g.
g.pixels
pixels
+ cast(size_t) y * g.
g.capW
capW
;
const
_error_ green
green
= h > 1 ? (y * 255) / (h - 1) : 0;
foreach (
(parameter) x
x
; 0 .. w)
{ const
_error_ red
red
= w > 1 ? (x * 255) / (w - 1) : 0;
row[x] = cast(uint)((red << 16) | (green << 8) | blue); } } } // Verify the gradient really is anchored to the current size: the four // corners of the w x h region must hold the expected channel extremes. // A stale or wrongly-strided buffer fails immediately (F02 requirement 1). void
void app.checkCorners() nothrow
checkCorners
() nothrow
{ if (g.
(field) _error_ g.pixels
pixels
is null || g.
(field) _error_ g.width
width
< 2 || g.
(field) _error_ g.height
height
< 2)
return; const
(local variable) const(_error_) w
w
= g.
(field) _error_ g.width
width
,
(local variable) const(_error_) h
h
= g.
(field) _error_ g.height
height
;
const
(local variable) const(_error_) blue
blue
= (g.
(field) _error_ g.frame
frame
* 4) & 0xff;
uint
uint app.checkCorners.at(int x, int y) pure nothrow @nogc @safe
at
(int
(parameter) int x
x
, int
(parameter) int y
y
) nothrow
{ return g.
(field) _error_ g.pixels
pixels
[cast(size_t) y * g.
g.capW
capW
+ x];
} const
(local variable) const(_error_) expTl
expTl
= cast(uint) blue;
const
(local variable) const(_error_) expTr
expTr
= cast(uint)((255 << 16) | blue);
const
(local variable) const(_error_) expBl
expBl
= cast(uint)((255 << 8) | blue);
const
(local variable) const(_error_) expBr
expBr
= cast(uint)((255 << 16) | (255 << 8) | blue);
const
(local variable) const(_error_) ok
ok
=
uint app.checkCorners.at(int x, int y) pure nothrow @nogc @safe
at
(0, 0) == expTl &&
uint app.checkCorners.at(int x, int y) pure nothrow @nogc @safe
at
(w - 1, 0) == expTr
&&
uint app.checkCorners.at(int x, int y) pure nothrow @nogc @safe
at
(0, h - 1) == expBl &&
uint app.checkCorners.at(int x, int y) pure nothrow @nogc @safe
at
(w - 1, h - 1) == expBr;
if (!ok) { ++g.
(field) _error_ g.checksFailed
checksFailed
;
logEvent("paint_check ok=0 size=%dx%d tl=%06x tr=%06x bl=%06x br=%06x",
undefined identifier `logEvent`
w, h, at(0, 0), at(w - 1, 0), at(0, h - 1), at(w - 1, h - 1)); } } // --------------------------------------------------------------------------- // The resize storm: 14 programmatic SetWindowPos steps covering pure grows, // pure shrinks, mixed grow/shrink, move-only and a same-size no-move step // (F02 requirement 2). Each step's messages dispatch re-entrantly inside // SetWindowPos; the per-step verdict logs whether a frame was presented. struct
(struct) app.StormStep
StormStep
{ const(char)*
(field) const(char)* app.StormStep.kind
kind
; // grow | shrink | mixed | move | same
int
(field) int app.StormStep.x
x
,
(field) int app.StormStep.y
y
; // position (move steps; others pass SWP_NOMOVE)
int
(field) int app.StormStep.w
w
,
(field) int app.StormStep.h
h
; // outer size (size steps; move steps pass SWP_NOSIZE)
UINT
(field) _error_ app.StormStep.extraFlags
extraFlags
; // SWP_NOMOVE or SWP_NOSIZE
undefined identifier `UINT`
} void
app.runResizeStorm
runResizeStorm
(HWND
(parameter) HWND hwnd
hwnd
) nothrow
undefined identifier `HWND`
{ static immutable
(unresolved type) StormStep
StormStep
[14]
StormStep[14] steps
steps
= [
StormStep("grow", 0, 0, 520, 360, SWP_NOMOVE), StormStep("grow", 0, 0, 640, 480, SWP_NOMOVE), StormStep("grow", 0, 0, 800, 600, SWP_NOMOVE), StormStep("grow", 0, 0, 1024, 768, SWP_NOMOVE), StormStep("shrink", 0, 0, 700, 500, SWP_NOMOVE), StormStep("shrink", 0, 0, 500, 350, SWP_NOMOVE), StormStep("shrink", 0, 0, 320, 240, SWP_NOMOVE), StormStep("mixed", 0, 0, 240, 640, SWP_NOMOVE), StormStep("mixed", 0, 0, 640, 240, SWP_NOMOVE), StormStep("move", 120, 120, 0, 0, SWP_NOSIZE), StormStep("move", 240, 180, 0, 0, SWP_NOSIZE), StormStep("same", 0, 0, 640, 240, SWP_NOMOVE), // same outer size StormStep("grow", 0, 0, 800, 600, SWP_NOMOVE), StormStep("shrink", 0, 0, 480, 320, SWP_NOMOVE), ]; logEvent("resize_storm_begin steps=%d invalidate=%d grow_only=%d", cast(int) steps.length, g.
g.noInvalidate
noInvalidate
? 0 : 1, g.
g.growOnly
growOnly
? 1 : 0);
foreach (
(parameter) i
i
,
(parameter) s
s
; steps)
{ logEvent("step name=SetWindowPos i=%d kind=%s pos=%d,%d size=%dx%d", cast(int) i, s.
s.kind
kind
, s.
s.x
x
, s.
s.y
y
, s.
s.w
w
, s.
s.h
h
);
const
_error_ framesBefore
framesBefore
= g.
g.frame
frame
;
const
_error_ wBefore
wBefore
= g.
g.width
width
,
_error_ hBefore
hBefore
= g.
g.height
height
;
SetWindowPos(hwnd, null, s.
s.x
x
, s.
s.y
y
, s.
s.w
w
, s.
s.h
h
,
SWP_NOZORDER | SWP_NOACTIVATE | s.
s.extraFlags
extraFlags
);
// The storm runs inside one WM_TIMER dispatch, so queued WM_PAINTs // would never be seen before DestroyWindow — present synchronously. // The InvalidateRect is load-bearing: a pure shrink invalidates // nothing by itself (the retained surface already covers the smaller // client area), so without it UpdateWindow is a no-op and the window // keeps a stale gradient. WSI_NO_INVALIDATE=1 demonstrates exactly // that (the step_result below records painted=0 for shrink steps). if (!g.
g.noInvalidate
noInvalidate
)
InvalidateRect(hwnd, null, FALSE); UpdateWindow(hwnd); const
_error_ painted
painted
= g.
g.frame
frame
!= framesBefore;
const
_error_ sizeChanged
sizeChanged
= g.
g.width
width
!= wBefore || g.
g.height
height
!= hBefore;
logEvent("step_result i=%d kind=%s painted=%d client=%dx%d", cast(int) i, s.
s.kind
kind
, painted ? 1 : 0, g.
g.width
width
, g.
g.height
height
);
// Stale only when the client size changed and no frame followed: the // window then shows the previous frame's gradient, wrongly anchored // for the new size (move-only / same-size steps are harmless). if (!painted && sizeChanged) logEvent("stale_content i=%d kind=%s was=%dx%d now=%dx%d " ~ "note=window_still_shows_frame_anchored_to_old_size", cast(int) i, s.
s.kind
kind
, wBefore, hBefore, g.
g.width
width
, g.
g.height
height
);
} logEvent("resize_storm_end wm_sizing_count=%u wm_entersizemove_count=%u " ~ "note=modal_resize_loop_not_reachable_programmatically_see_f03", g.
g.sizingCount
sizingCount
, g.
g.sizeMoveCount
sizeMoveCount
);
logEvent("paint_checks failed=%u", g.
g.checksFailed
checksFailed
);
DestroyWindow(hwnd); } // --------------------------------------------------------------------------- // The window procedure: every F02-relevant message is logged with its payload. extern (Windows) LRESULT
app.wndProc
wndProc
(HWND
(parameter) HWND hwnd
hwnd
, UINT
(parameter) UINT msg
msg
, WPARAM wParam, LPARAM lParam) nothrow
undefined identifier `LRESULT`
undefined identifier `HWND`
undefined identifier `UINT`
undefined identifier `WPARAM`
undefined identifier `LPARAM`
{ switch (msg) { case WM_NCCREATE: logEvent("msg name=WM_NCCREATE"); goto default; case WM_NCCALCSIZE: logEvent("msg name=WM_NCCALCSIZE"); goto default; case WM_CREATE: logEvent("msg name=WM_CREATE"); g.
g.memDc
memDc
= CreateCompatibleDC(null);
// druntime's core.sys.windows has no GetDpiForWindow (Win10 1607+); // the system DPI from the screen DC is enough for the scale= field. HDC
_error_ screen
screen
= GetDC(null);
g.
g.dpi
dpi
= GetDeviceCaps(screen, LOGPIXELSX);
ReleaseDC(null, screen); return 0; case WM_SHOWWINDOW: logEvent("msg name=WM_SHOWWINDOW shown=%d", cast(int) wParam); goto default; case WM_ENTERSIZEMOVE: // interactive size/move modal loop — F03's subject case WM_EXITSIZEMOVE: ++g.
g.sizeMoveCount
sizeMoveCount
;
logEvent("msg name=%s", msg == WM_ENTERSIZEMOVE ? "WM_ENTERSIZEMOVE".ptr : "WM_EXITSIZEMOVE".ptr); goto default; case WM_SIZING: // only the interactive border drag produces this ++g.
g.sizingCount
sizingCount
;
const
_error_ r
r
= cast(RECT*) lParam;
logEvent("msg name=WM_SIZING edge=%d rect=%ld,%ld-%ld,%ld", cast(int) wParam, r.left, r.top, r.right, r.bottom); goto default; case WM_WINDOWPOSCHANGING: const
_error_ wpg
wpg
= cast(WINDOWPOS*) lParam;
logEvent("msg name=WM_WINDOWPOSCHANGING pos=%d,%d size=%dx%d flags=0x%04x", wpg.
wpg.x
x
, wpg.
wpg.y
y
, wpg.cx, wpg.cy, wpg.flags);
goto default; case WM_WINDOWPOSCHANGED: const
_error_ wpc
wpc
= cast(WINDOWPOS*) lParam;
logEvent("msg name=WM_WINDOWPOSCHANGED pos=%d,%d size=%dx%d flags=0x%04x", wpc.
wpc.x
x
, wpc.
wpc.y
y
, wpc.cx, wpc.cy, wpc.flags);
goto default; // DefWindowProcW synthesizes WM_SIZE/WM_MOVE from this case WM_MOVE: logEvent("msg name=WM_MOVE pos=%d,%d", cast(int) cast(short)(lParam & 0xffff), cast(int) cast(short)((lParam >> 16) & 0xffff)); return 0; case WM_SIZE: const
_error_ w
w
= cast(int)(lParam & 0xffff);
const
_error_ h
h
= cast(int)((lParam >> 16) & 0xffff);
logEvent("msg name=WM_SIZE wparam=%d size=%dx%d", cast(int) wParam, w, h); if (!g.
g.firstSizeSeen
firstSizeSeen
)
{ g.
g.firstSizeSeen
firstSizeSeen
= true;
logEvent("first_configure size=%dx%d", w, h); } logEvent("resize size=%dx%d scale=%d.%02d", w, h, g.
g.dpi
dpi
/ 96, (g.
g.dpi
dpi
% 96) * 100 / 96);
if (wParam == SIZE_MINIMIZED) return 0; if (w != g.
g.width
width
|| h != g.
g.height
height
)
createBackbuffer(w, h); return 0; case WM_ERASEBKGND: logEvent("msg name=WM_ERASEBKGND"); return 1; // claim erased — WM_PAINT repaints the full client anyway case WM_PAINT: logEvent("msg name=WM_PAINT"); PAINTSTRUCT
_error_ ps
ps
;
HDC
_error_ hdc
hdc
= BeginPaint(hwnd, &ps);
++g.
g.frame
frame
;
drawGradient(); checkCorners(); if (g.
g.pixels
pixels
!is null)
BitBlt(hdc, 0, 0, g.
g.width
width
, g.
g.height
height
, g.
g.memDc
memDc
, 0, 0, SRCCOPY);
if (!g.
g.firstPaintDone
firstPaintDone
)
{ g.
g.firstPaintDone
firstPaintDone
= true;
logEvent("first_pixel_presented size=%dx%d", g.
g.width
width
, g.
g.height
height
);
} logEvent("frame_callback t=%lld frame=%u size=%dx%d", nowUs(), g.
g.frame
frame
, g.
g.width
width
, g.
g.height
height
);
EndPaint(hwnd, &ps); return 0; case WM_TIMER: if (wParam != TIMER_ID) return 0; ++g.
g.ticks
ticks
;
InvalidateRect(hwnd, null, FALSE); // schedule the next WM_PAINT if (g.
g.autoExit
autoExit
&& g.
g.ticks
ticks
== STORM_AFTER_TICKS)
runResizeStorm(hwnd); // ends in DestroyWindow return 0; case WM_CLOSE: logEvent("close_requested"); goto default; // DefWindowProcW responds with DestroyWindow case WM_DESTROY: logEvent("msg name=WM_DESTROY"); KillTimer(hwnd, TIMER_ID); releaseBackbuffer(); if (g.
g.memDc
memDc
!is null)
{ DeleteDC(g.
g.memDc
memDc
);
g.
g.memDc
memDc
= null;
} PostQuitMessage(0); return 0; case WM_NCDESTROY: logEvent("msg name=WM_NCDESTROY"); goto default; default: return DefWindowProcW(hwnd, msg, wParam, lParam); } } // --------------------------------------------------------------------------- bool
bool app.envFlag(const(wchar)* name) nothrow
envFlag
(const(wchar)*
(parameter) const(wchar)* name
name
) nothrow
{ WCHAR[8]
(local variable) _error_ buf
buf
;
undefined identifier `WCHAR`
const
(local variable) const(_error_) n
n
= GetEnvironmentVariableW(name, buf.ptr, buf.length);
undefined identifier `GetEnvironmentVariableW`
return n >= 1 && n < buf.length && buf[0] == '1'; } int
int D main()
main
()
{ instrumentInit("f02_resize_win32");
undefined identifier `instrumentInit`
logEvent("init_start");
undefined identifier `logEvent`
g.
g.autoExit
autoExit
= envFlag("WSI_AUTO_EXIT"w.ptr);
g.
g.noInvalidate
noInvalidate
= envFlag("WSI_NO_INVALIDATE"w.ptr);
g.
g.growOnly
growOnly
= envFlag("WSI_GROW_ONLY"w.ptr);
logEvent("mode auto_exit=%d invalidate=%d grow_only=%d",
undefined identifier `logEvent`
g.
g.autoExit
autoExit
? 1 : 0, g.
g.noInvalidate
noInvalidate
? 0 : 1, g.
g.growOnly
growOnly
? 1 : 0);
logEvent("step name=GetModuleHandleW");
undefined identifier `logEvent`
HINSTANCE
(local variable) _error_ hInst
hInst
= GetModuleHandleW(null);
undefined identifier `HINSTANCE`
undefined identifier `GetModuleHandleW`
logEvent("step name=LoadCursorW");
undefined identifier `logEvent`
HCURSOR
(local variable) _error_ arrow
arrow
= LoadCursorW(null, IDC_ARROW);
undefined identifier `HCURSOR`
undefined identifier `LoadCursorW`
auto
(local variable) wstring clsName
clsName
= "wsi-f02-class"w;
WNDCLASSEXW
(local variable) _error_ wc
wc
;
undefined identifier `WNDCLASSEXW`
wc.cbSize = WNDCLASSEXW.sizeof; wc.lpfnWndProc = &wndProc; wc.hInstance = hInst; wc.lpszClassName = clsName.ptr; wc.hCursor = arrow; // No hbrBackground: WM_ERASEBKGND is handled, the DIB covers every pixel. logEvent("step name=RegisterClassExW");
undefined identifier `logEvent`
if (!RegisterClassExW(&wc))
undefined identifier `RegisterClassExW`
{ logEvent("error what=RegisterClassExW code=%lu", GetLastError());
undefined identifier `logEvent`
return 1; } logEvent("step name=CreateWindowExW");
undefined identifier `logEvent`
HWND
(local variable) _error_ hwnd
hwnd
= CreateWindowExW(0, clsName.ptr, "wsi-f02-resize"w.ptr,
undefined identifier `HWND`
undefined identifier `CreateWindowExW`
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 480, 320, null, null, hInst, null); if (hwnd is null) { logEvent("error what=CreateWindowExW code=%lu", GetLastError());
undefined identifier `logEvent`
return 1; } logEvent("window_created");
undefined identifier `logEvent`
logEvent("step name=ShowWindow");
undefined identifier `logEvent`
ShowWindow(hwnd, SW_SHOW);
undefined identifier `ShowWindow`
logEvent("step name=UpdateWindow");
undefined identifier `logEvent`
UpdateWindow(hwnd); // forces the first WM_PAINT synchronously, now
undefined identifier `UpdateWindow`
logEvent("step name=SetTimer interval_ms=%d", TICK_MS);
undefined identifier `logEvent`
SetTimer(hwnd, TIMER_ID, TICK_MS, null);
undefined identifier `SetTimer`
MSG
(local variable) _error_ msg
msg
;
undefined identifier `MSG`
while (GetMessageW(&msg, null, 0, 0) > 0)
undefined identifier `GetMessageW`
{ TranslateMessage(&msg);
undefined identifier `TranslateMessage`
DispatchMessageW(&msg);
undefined identifier `DispatchMessageW`
} logEvent("exit code=%d", cast(int) msg.wParam);
undefined identifier `logEvent`
return cast(int) msg.wParam; }