You'll notice PeekMessage A) doesnt warn about non-references even though the warning code is there and B) Yields a ton of "attempt to free unreferenced scalar" errors. The problem was an else{} in the wrong place, and making array values mortal so they got cleaned up before they ever hit your perl program, so here's it fixed.
########################################################################### # (@)METHOD:PeekMessage([MIN, MAX, MESSAGE]) # Inspects the window's message queue and eventually returns data # about the message it contains; it can optionally check only for message # identifiers in the range MIN..MAX; the last MESSAGE parameter, if # specified, must be an array reference. # If a message is found, the function puts in that array 7 elements # containing: # - the handle of the window to which the message is addressed # - the message identifier # - the wParam argument # - the lParam argument # - the time when message occurs # - the x coordinate at which message occurs # - the y coordinate at which message occurs # BOOL PeekMessage(handle, min=0, max=0, message=&PL_sv_undef) HWND handle UINT min UINT max SV* message PREINIT: MSG msg; CODE: ZeroMemory(&msg, sizeof(msg)); RETVAL = PeekMessage(&msg, handle, min, max, PM_NOREMOVE); if(message != &PL_sv_undef && SvROK(message)) { if(SvTYPE(SvRV(message)) == SVt_PVAV) { av_clear((AV*) SvRV(message)); av_push((AV*) SvRV(message), newSViv((long) msg.hwnd)); av_push((AV*) SvRV(message), newSViv(msg.message)); av_push((AV*) SvRV(message), newSViv(msg.wParam)); av_push((AV*) SvRV(message), newSViv(msg.lParam)); av_push((AV*) SvRV(message), newSViv(msg.time)); av_push((AV*) SvRV(message), newSViv(msg.pt.x)); av_push((AV*) SvRV(message), newSViv(msg.pt.y)); } } else { if(PL_dowarn) warn("Win32::GUI: fourth parameter to PeekMessage is not an array reference"); } OUTPUT: RETVAL