proc LastError
begin
        pushad
        invoke  GetLastError
        stdcall ErrorMessage, eax
        popad
        return
endp

;-------------------------------------------------------------------------
; Shows message box with error message.
; Arguments:
;  errorcode - code of the error. This is code returned by GetLastError.
;
;  Because of missing information about "Message table" resources, this
;  procedure uses specific processing for application defined messages
;-------------------------------------------------------------------------
proc ErrorMessage, .errorcode
.errstr dd ?
begin
        pushad

        test    [.errorcode], errFresh
        jnz     .freshmsg

        lea     esi, [.errstr]
        invoke  FormatMessageW, FORMAT_MESSAGE_ALLOCATE_BUFFER or                \
                               FORMAT_MESSAGE_FROM_SYSTEM,                      \
                               NULL, [.errorcode], NULL, esi, 256, NULL
        invoke  GetFocus
        push    eax
        invoke  MessageBoxW, [hMainForm], [.errstr], NULL, MB_OK or MB_ICONERROR
        invoke  LocalFree, [.errstr]
        invoke  SetFocus ; from the stack
.finish:
        popad
        return

.freshmsg:
        cmp     [.errorcode], errCanceled
        je      .finish

        mov     esi, FreshErrorMessages-12

; search for message
.loop:
        add     esi, 12
        mov     eax, [esi]      ; error code
        test    eax, eax
        jz      .notfound

        cmp     eax, [.errorcode]
        jne     .loop

;found:
        mov     edi, [esi+4]    ; message type
        mov     esi, [esi+8]    ; pointer to the message string

.msg:
        test    edi, edi        ; is it errtypeNULL
        jz      .finish

        invoke  GetFocus
        push    eax
        invoke  MessageBoxW, [hMainForm], esi, NULL, edi
        invoke  SetFocus ; from the stack
        popad
        return

.notfound:
        mov     ecx, errmsgUnknownError
        mov     edx, MB_OK or MB_ICONERROR
        jmp     .msg

endp


answerYesNo        = MB_YESNO
answerYesNoCancel  = MB_YESNOCANCEL
answerRetryCancel  = MB_RETRYCANCEL

iglobal
  cAskQuestionTitle du "Question?", 0
endg

proc AskQuestion, .hQuestion, .hParent, .answers
begin
        push    ebx ecx edx

        invoke  GetFocus
        mov     ebx, eax

        stdcall utf8ToWideChar, [.hQuestion]
        push    eax

        mov     ecx, [.answers]
        or      ecx, MB_ICONQUESTION

        invoke  MessageBoxW, [.hParent], eax, cAskQuestionTitle, ecx
        stdcall FreeMem ; form the stack

        push    eax
        invoke  SetFocus, ebx
        pop     eax

        pop     edx ecx ebx
        return
endp