;
 ; ------------------------------------------------------
 ;        Mid$(sStr, lPos, [lLen]) = sSubStr
 ;        MidS(sStr, lPos, [lLen]) = sSubStr
 ; ------------------------------------------------------
 ;
 ; Property Let MidS(sStr As String, _
 ;                   ByVal lPos As Long, _
 ;          Optional ByVal lLen As Long, _
 ;                   sSubStr As String)
 ; End Property
 ;
 ; ------------------------------------------------------
;
 .686         ; 32-bit instruction set
 .model flat  ; Protected memory, 4GB limit
 .code        ; Start of code

MidS proc near

   push esi
   push edi      ; preserve registers
   push ebx

   mov edi,[esp+20] ; copy string descriptor
   mov edx,[esp+24] ; copy position parameter
   mov eax,[esp+28] ; copy length parameter
   mov esi,[esp+32] ; copy sub-str descriptor

   mov edi,[edi]    ; extract string pointer
   mov esi,[esi]    ; extract sub-str pointer
   test edi,edi     ; validate string pointer
   jz _exitp        ; exit null string passed
   test esi,esi     ; validate sub-str pointer
   jz _exitp        ; exit null string assigned

   mov ebx,[edi-4]  ; extract string byte length
   mov ecx,[esi-4]  ; extract sub-str byte length
   shr ebx, 1       ; convert to unicode chr count
  ;jz _exitp        ; exit if empty string passed
   dec edx          ; convert pos to zero base
  ;js _exitp        ; exit if invalid start pos
   shr ecx, 1       ; convert to unicode chr count
   jz _exitp        ; exit empty sub-str assigned

   sub ebx, edx     ; sub start pos from length
   jbe _exitp       ; start outside str bounds

   test eax,eax     ; eax = insert length
   jz _uselen       ; edi = str start pos
   js _exitp        ; ebx = len to str end
   cmp eax, ecx     ; esi = assigned str
   cmovb ecx,eax    ; ecx = allocated len
                    ; edx = insert pos
  _uselen:
   lea edi,[edi+edx*2] ; calc insert start
   xor eax, eax        ; init offset ptr
   cmp ebx, ecx        ; validate insert len
   cmovb ecx,ebx       ; insert to str end

  _dofill:
   mov dx,[esi+eax*2]  ; extract char into dx
   mov [edi+eax*2],dx  ; insert char into str
   inc eax
   dec ecx
   jnz _dofill

  _exitp:
   pop ebx
   pop edi       ; restore registers
   pop esi
   xor eax, eax  ; clear eax tell VB all okay
   ret 20        ; cleanup (lpObj, p1, p2, p3, p4)

MidS endp  ; end of procedure
end MidS   ; end of code, indicate entry point
