;************************************************************************************
; Get the text of the [Control] using WM_GETTEXT and returns a handle of the string.
;************************************************************************************
proc GetControlTextUtf8, .Control
begin
        push    ebx ecx edx

        invoke  SendMessageW, [.Control], WM_GETTEXTLENGTH, 0, 0

        lea     ecx, [eax+1]
        lea     eax, [4*ecx+255]
        and     eax, $ffffff00

        stdcall GetMem, eax
        mov     ebx, eax

        invoke  SendMessageW, [.Control], WM_GETTEXT, ecx, ebx

        stdcall WideCharToUtf8, ebx
        stdcall FreeMem, ebx

        pop     edx ecx ebx
        return
endp



;************************************************************************************
; Get the text of the [Control] using WM_GETTEXT and returns a handle of the string.
;************************************************************************************
proc GetControlTextW, .Control
begin
        push    ebx ecx edx

        invoke  SendMessageW, [.Control], WM_GETTEXTLENGTH, 0, 0

        lea     ecx, [eax+1]
        lea     eax, [4*ecx+255]
        and     eax, $ffffff00
        stdcall GetMem, eax
        mov     ebx, eax

        invoke  SendMessageW, [.Control], WM_GETTEXT, ecx, ebx
        mov     eax, ebx

        pop     edx ecx ebx
        return
endp



;************************************************************************************
; Get the text of the [Control] using WM_GETTEXT and returns a handle of the string.
;************************************************************************************
proc GetDlgItemTextUtf8, .hwnd, .id
begin
        push    ecx edx

        invoke  GetDlgItem, [.hwnd], [.id]
        stdcall GetControlTextUtf8, eax
        pop     edx ecx
        return
endp




;*******************************************************************************
; Sets the text in control using WM_SETTEXT from string with handle or pointer
; in [string].
;*******************************************************************************
proc SetControlTextUtf8, .Control, .string
begin
        push    eax ecx edx

        stdcall utf8ToWideChar, [.string]
        push    eax

        invoke  SendMessageW, [.Control], WM_SETTEXT, 0, eax

        stdcall FreeMem ; from the stack
        pop     edx ecx eax
        return
endp



proc SetDlgItemTextUtf8, .hwnd, .id, .string
begin
        push    eax ecx edx

        invoke  GetDlgItem, [.hwnd], [.id]
        stdcall SetControlTextUtf8, eax, [.string]

        pop     edx ecx eax
        return
endp




proc GetFullPathNameUtf8, .hFilename
.filename dd ?
begin
        pushad

        stdcall utf8ToWideChar, [.hFilename]
        mov     esi, eax

        stdcall GetMem, 4096
        mov     edi, eax

        lea     eax, [.filename]
        invoke  GetFullPathNameW, esi, 2048, edi, eax

        stdcall WideCharToUtf8, edi
        mov     [esp+4*regEAX], eax

        stdcall FreeMem, edi
        stdcall FreeMem, esi

        popad
        return
endp



; Checks whether the path ends with "\" and if not, adds one at the end.

proc FixPathEnd, .hPath
begin
        push    eax

        stdcall StrClipSpacesR, [.hPath]
        stdcall StrClipSpacesL, [.hPath]

        stdcall StrPtr,  [.hPath]
        add     eax, [eax+string.len]
        cmp     byte [eax-1], '\'
        je      .finish

        stdcall StrCharCat, [.hPath], '\'

.finish:
        pop     eax
        return
endp



proc UnFixPathEnd, .hPath
begin
        push    eax ecx

        stdcall StrClipSpacesR, [.hPath]
        stdcall StrClipSpacesL, [.hPath]

        stdcall StrPtr,  [.hPath]
        mov     ecx, eax
        add     ecx, [eax+string.len]
        cmp     byte [ecx-1], '\'
        je      .remove
        cmp     byte [ecx-1], '/'
        jne     .finish

.remove:
        dec     [eax+string.len]
        mov     byte [ecx-1], 0

.finish:
        pop     ecx eax
        return
endp



;proc RemoveEndSlash, .hPath
;begin
;        push    edi ebx
;        stdcall StrPtr, [.hPath]
;        mov     edi, eax
;        stdcall StrLen, [.hPath]
;        mov     ebx, eax
;
;        cmp     byte [edi+ebx-1], '\'
;        je      .killslash
;        cmp     byte [edi+eax-1], '/'
;        jne     .pathok                 ; well more checks need, but later...
;
;.killslash:
;        mov     byte [edi+eax-1], 0
;
;.pathok:
;        pop     ebx edi
;        return
;endp




;************************************************************************************
; Get the text of the [Control] using WM_GETTEXT and returns a handle of the string.
;************************************************************************************
proc GetListboxTextUtf8, .hListbox, .idxItem
begin
        push    ebx ecx edx

        invoke  SendMessageW, [.hListbox], LB_GETTEXTLEN, [.idxItem], 0

        lea     ecx, [eax+1]
        lea     eax, [4*eax+4]

        stdcall GetMem, eax
        mov     ebx, eax

        invoke  SendMessageW, [.hListbox], LB_GETTEXT, [.idxItem], ebx

        stdcall WideCharToUtf8, ebx
        stdcall FreeMem, ebx

        pop     edx ecx ebx
        return
endp


; returns:
;   eax - pointer to the converted text
;   ecx - character count
;   edx - the code table that has been used.



proc InteractivelyConvertAnsiText, .pText, .len
.res dd ?
begin
        pushad

        mov     esi, CP_UTF8

.convert_loop:
        xor     eax, eax
        invoke  MultiByteToWideChar, esi, MB_ERR_INVALID_CHARS, [.pText], [.len], eax, eax
        test    eax, eax
        jnz     .converted

        stdcall SelectANSIEncoding, [.pText], [.len]
        jc      .finish_err_cancel

        mov     esi, eax
        jmp     .convert_loop

.converted:

        lea     ecx, [2*eax+256]
        stdcall GetMem, ecx
        jc      .finish_err_memory

        mov     edi, eax
        shr     ecx, 1
        invoke  MultiByteToWideChar, esi, MB_ERR_INVALID_CHARS, [.pText], [.len], edi, ecx

        xor     ecx, ecx
        mov     dword [edi+2*eax], ecx

        mov     [esp+4*regEAX], edi
        mov     [esp+4*regECX], eax
        mov     [esp+4*regEDX], esi

        clc
        popad
        return

.finish_err_memory:

        mov     dword [esp+4*regEAX], $0e     ; windows ERROR_OUTOFMEMORY
        stc
        popad
        return


.finish_err_cancel:

        mov    dword [esp+4*regEAX], $0b      ; windows ERROR_BAD_FORMAT
        stc
        popad
        return
endp