; ----------------------- ; HiAsm Runtime Library ; ----------------------- ; in: eax - size ; out: eax - pointer proc __alloc invoke HeapAlloc,[pheap],HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY,eax ret endp ; in: eax - pointer, edx - new size ; out: eax - pointer proc __realloc invoke HeapReAlloc,[pheap],HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY,eax,edx ret endp ; in: eax - pointer proc __free invoke HeapFree,[pheap],0,eax ret endp ; in: eax - pchar ; out eax - len (includes #00) proc __strlen push edi mov edi,eax xor eax,eax mov ecx,-1 cld repne scasb sub eax,ecx dec eax pop edi ret endp ; in: eax - dest, edx - source proc __strcpy push esi edi eax mov eax,edx call __strlen mov ecx,eax mov esi,edx pop edi cld rep movsb pop edi esi ret endp ; in: eax - str1, edx - str2; out: eax - diff char proc __strcmp push esi edi eax mov eax,edx call __strlen mov ecx,eax mov esi,edx pop edi cld rep cmpsb xor eax,eax mov al,[edi-1] sub al,[esi-1] pop edi esi ret endp ; in: eax - dest, edx - source, ecx - len proc __memcpy push esi edi mov esi,edx mov edi,eax cld rep movsb mov eax,edi pop edi esi ret endp ; in: eax - dest, edx - source, ecx - len proc __memmove push esi edi mov esi,edx mov edi,eax cmp esi,edi jb .L1 cld rep movsb jmp .L2 .L1: std add esi,ecx add edi,ecx dec esi dec edi rep movsb cld .L2: pop edi esi ret endp ; in: al - char, edx - dest, ecx - len proc __memset push edi mov edi,edx cld rep stosb pop edi ret endp ; out: eax - empty data proc __empty_event dt mov eax,empty_data ret endp ; --------------- ; data_str type ; --------------- ; in: edx - str_var_ptr proc __strclear push eax mov eax,[edx] or eax,eax je .L1 mov dword [edx],0 sub eax,8 mov ecx,[eax] dec ecx js .L1 mov [eax],ecx jne .L1 push edx call __free pop edx .L1:pop eax ret endp ; in: edx - str_var_ptr, eax - new len proc __strsetlength mov ecx,[edx] or ecx,ecx je .L1 cmp dword [ecx-8],1 je .L2 .L1:push ecx call __strclear push edx push eax add eax,9 call __alloc mov dword [eax],1 pop dword [eax+4] add eax,8 pop edx mov [edx],eax mov ecx,[eax-4] pop edx or edx,edx je .L3 cmp ecx,[edx-4] jb @f mov ecx,[edx-4] @@: jmp __memcpy .L2:cmp dword [ecx-4],eax je .L3 push edx push eax mov edx,eax add edx,9 mov eax,ecx sub eax,8 call __realloc pop dword [eax+4] add eax,8 pop edx mov [edx],eax .L3:ret endp ; in: edx - str_var_ptr, eax - str to duplicate proc __strdup call __strclear virtual at 0 jmp __strdupnoclear end virtual endp ; in: edx - str_var_ptr, eax - str to duplicate proc __strdupnoclear mov [edx],eax mov ecx,[eax-8] inc ecx je .L1 mov [eax-8],ecx .L1:ret endp ; in: edx - str_var_ptr, eax - pchar to copy proc __strpcopy or eax,eax je .exit push edx push eax call __strlen push eax mov edx,[esp+8] call __strsetlength pop ecx pop edx pop eax mov eax,[eax] jmp __memcpy .exit: jmp __strclear endp ; in: edx - str_var_ptr, eax - pchar to copy, ecx - length proc __strnpcopy or eax,eax je .exit jcxz .exit push edx push eax push ecx mov eax,ecx inc eax mov edx,[esp+8] call __strsetlength pop ecx pop edx pop eax mov eax,[eax] call __memcpy mov byte [eax],0 ret .exit: jmp __strclear endp ; in: edx - str_var_ptr, eax - str2 proc __strcat locals str dd ? str2 dd ? len dd ? len2 dd ? endl mov [str],edx mov [str2],eax mov eax,[edx] call __strlen dec eax mov [len],eax mov eax,[str2] call __strlen mov [len2],eax dec eax add eax,[len] mov edx,[str] mov edx,[edx] cmp dword [edx-8],1 jne .resize cmp eax,[edx-4] jbe .noresize .resize: mov edx,[str] call __strsetlength .noresize: mov eax,[str] mov eax,[eax] add eax,[len] mov edx,[str2] mov ecx,[len2] call __memcpy ret endp ; in: eax - str, edx - str to search, ecx - start pos; out: eax - pos proc __strpos locals str dd ? str2 dd ? endl push esi edi mov [str],eax mov [str2],edx dec ecx add eax,ecx mov edi,eax call __strlen mov ecx,eax .loop: mov esi,[str2] lodsb repne scasb jcxz .notfound push ecx push edi rep cmpsb cmp byte [esi-1],0 je .found pop edi pop ecx jcxz .notfound jmp .loop .found: pop eax pop ecx sub eax,[str] jmp .exit .notfound: xor eax,eax .exit: pop edi esi ret endp ; in: edx - str_var_ptr, eax - pos, ecx - count proc __strdelete locals str dd ? pos dd ? cnt dd ? endl mov [str],edx mov [pos],eax mov [cnt],ecx cmp eax,1 jb .exit mov eax,[edx] mov eax,[eax-4] call __strsetlength mov edx,[str] mov eax,[edx] call __strlen sub eax,[pos] jbe .exit sub eax,[cnt] jbe .cut mov ecx,eax inc ecx mov eax,[str] mov eax,[eax] add eax,[pos] dec eax mov edx,eax add edx,[cnt] call __memcpy jmp .exit .cut: mov eax,[str] mov eax,[eax] add eax,[pos] dec eax mov byte [eax],0 .exit: ret endp ; in: edx - str_var_ptr, eax - pos, ecx - count proc __strcopy locals str dd ? pos dd ? cnt dd ? endl mov [str],edx mov [pos],eax mov [cnt],ecx mov eax,[edx] mov eax,[eax-4] call __strsetlength mov edx,[str] mov eax,[edx] call __strlen sub eax,[pos] jbe .empty cmp eax,[cnt] jae @f mov [cnt],eax @@:mov edx,[str] mov eax,[edx] mov edx,eax add edx,[pos] dec edx mov ecx,[cnt] call __memcpy mov edx,[str] mov eax,[edx] add eax,[cnt] jmp .cut .empty: mov edx,[str] mov eax,[edx] .cut: mov byte [eax],0 .exit: ret endp ; in: edx - str_var_ptr, eax - substr, ecx - pos proc __strinsert locals str dd ? st2 dd ? pos dd ? len dd ? endl mov [str],edx mov [st2],eax mov [pos],ecx call __strlen dec eax je .exit mov [len],eax mov eax,[edx] mov eax,[eax-4] add eax,[len] call __strsetlength mov edx,[str] mov eax,[edx] call __strlen cmp eax,[pos] jae @f mov [pos],eax @@:sub eax,[pos] mov ecx,eax mov edx,[str] mov eax,[edx] add eax,[pos] dec eax push eax mov edx,eax add eax,[len] push eax ecx call __memmove pop ecx edx add edx,ecx mov byte [edx],0 pop eax mov ecx,[len] mov edx,[st2] call __memcpy .exit: ret endp ; in: edx - str_var_ptr, eax - str to search, ecx - replace with proc __strreplace locals str dd ? src dd ? dest dd ? destlen dd ? diff dd ? endl push esi edi mov [str],edx mov [src],eax mov [dest],ecx mov eax,[edx] mov eax,[eax-4] call __strsetlength mov edx,[str] mov edi,[edx] mov eax,[dest] call __strlen mov [diff],eax dec eax mov [destlen],eax mov eax,[src] call __strlen sub [diff],eax mov eax,edi call __strlen mov ecx,eax cld .loop: mov esi,[src] lodsb repne scasb jcxz .exit push ecx push edi rep cmpsb cmp byte [esi-1],0 je .found pop edi pop ecx jcxz .exit jmp .loop .found: mov eax,[diff] test eax,eax je .noshift dec edi inc ecx mov edx,[str] mov eax,[edx] sub edi,eax push ecx mov eax,[eax-4] add eax,[diff] call __strsetlength pop ecx mov edx,[str] add edi,[edx] mov edx,edi mov eax,edi add eax,[diff] call __memmove .noshift: pop edi dec edi mov esi,[dest] mov ecx,[destlen] rep movsb pop ecx inc ecx add ecx,[diff] sub ecx,[destlen] jcxz .exit jmp .loop .exit: pop edi edi edi esi ret endp ; in: esi - pchar, out: eax - fileext, edx - filename proc __strfilepart xor ecx,ecx mov edx,ecx .loop: lodsb cmp al,'.' jne @f mov ecx,esi jmp .loop @@:cmp al,'\' jne @f mov edx,esi xor ecx,ecx jmp .loop @@:or al,al jne .loop mov eax,ecx ret endp ; esi - pchar proc __trimleft .loop: lodsb cmp al,' ' je .loop cmp al,9 je .loop dec esi ret endp ; in: edi - pchar, eax - num, ebx - base proc __int2str xor ecx,ecx or eax,eax jns .new mov byte [edi],'-' inc edi neg eax .new: ; получаем новую цифру xor edx,edx div ebx push edx inc ecx test eax,eax jne .new .loop: ; переводим в ASII pop eax add al,30h cmp al,'9' jng .ok add al,7 .ok: ; и заносим в буфер stosb loop .loop mov al,0 stosb ret endp proc IntToStr number,str_var,base push edi ebx mov edx,[str_var] mov eax,15 call __strsetlength mov eax,[str_var] mov edi,[eax] push edi mov eax,[number] mov ebx,[base] call __int2str pop eax ebx edi ret endp ; in: esi - pchar, ebx - base, out: esi - rest, eax - num proc __str2int xor eax,eax mov edx,eax mov ecx,eax or esi,esi je .ok1 call __trimleft cmp al,'-' jne .loop inc esi inc ecx .loop: lodsb test al,al je .end sub al,'0' cmp al,9 jle .ok sub al,7 cmp al,10 jb .end .ok: cmp al,bl jae .end imul edx,ebx add edx,eax jmp .loop .end: jcxz .ok1 neg edx .ok1: mov eax,edx dec esi ret endp proc StrToInt str,base push esi ebx mov esi,[str] mov ebx,[base] call __str2int pop ebx esi ret endp proc StrToOleStr str locals len dd ? endl mov eax,[str] call __strlen add eax,eax call __alloc push eax lea ecx,[len] invoke MultiByteToWideChar,0,0,[str],-1,eax,ecx pop eax ret endp ; ---------------- ; data_data type ; ---------------- ; in: edx - data_var_ptr proc __dataclear push eax edx mov eax,[edx] or eax,eax je .L1 mov dword [edx],0 .loop: mov ecx,[eax] dec ecx js .L1 mov [eax],ecx jne .L1 mov dl,[eax+8] cmp dl,data_str jne .free lea edx,[eax+12] call __strclear .free: push dword [eax+4] call __free pop eax or eax,eax jne .loop .L1:pop edx eax ret endp ; in: edx - data_var_ptr, eax - data to duplicate proc __datadup call __dataclear virtual at 0 jmp __datadupnoclear end virtual endp ; in: edx - data_var_ptr, eax - data to duplicate proc __datadupnoclear mov [edx],eax mov ecx,[eax] inc ecx je .L1 mov [eax],ecx .L1:ret endp proc IntToData val,data_var mov edx,[data_var] call __dataclear mov eax,16 call __alloc mov edx,[data_var] mov [edx],eax mov dword [eax],1 mov dword [eax+4],0 mov byte [eax+8],data_int mov ecx,[val] mov [eax+12],ecx ret endp proc StrToData val,data_var mov edx,[data_var] call __dataclear mov eax,16 call __alloc mov edx,[data_var] mov [edx],eax push eax mov dword [eax],1 mov dword [eax+4],0 mov byte [eax+8],data_str lea edx,[eax+12] mov eax,[val] call __strdup pop eax ret endp proc RealToData val,data_var mov edx,[data_var] call __dataclear mov eax,20 call __alloc mov edx,[data_var] mov [edx],eax push eax mov dword [eax],1 mov dword [eax+4],0 mov byte [eax+8],data_real cmp byte [val],1 je .L1 mov edx,[val] fld qword [edx] .L1:fstp qword [eax+12] fwait pop eax ret endp proc DataToInt data mov eax,[data] or eax,eax je .null mov dl,[eax+8] or dl,dl je .null cmp dl,data_int jne .noint mov eax,[eax+12] jmp .end .noint: cmp dl,data_str jne .nostr stdcall StrToInt,[eax+12],10 jmp .end .nostr: cmp dl,data_real jne .noreal fld qword [eax+12] fistp dword [esp-4] fwait mov eax,[esp-4] jmp .end .noreal: .null: xor eax,eax .end: ret endp proc DataToStr data,str mov eax,[data] or eax,eax je .null mov dl,[eax+8] or dl,dl je .null cmp dl,data_int jne .noint stdcall IntToStr,[eax+12],[str],10 jmp .end .noint: cmp dl,data_str jne .nostr mov eax,[eax+12] jmp .strdup .nostr: cmp dl,data_real jne .noreal fld qword [eax+12] stdcall RealToStr,[str] jmp .end .noreal: .null: mov eax,empty_string .strdup: mov edx,[str] call __strdup .end: ret endp proc DataToReal data mov eax,[data] or eax,eax je .null mov dl,[eax+8] or dl,dl je .null cmp dl,data_int jne .noint fild dword [eax+12] jmp .end .noint: cmp dl,data_str jne .nostr stdcall StrToReal,[eax+12] jmp .end .nostr: cmp dl,data_real jne .noreal fld qword [eax+12] jmp .end .noreal: .null: fldz .end: ret endp ; ---------------- ; data_real type ; ---------------- proc math.add faddp st1,st0 ret endp proc math.sub fsubp st1,st0 ret endp proc math.div fdivp st1,st0 ret endp proc math.mul fmulp st1,st0 ret endp proc math.idiv locals x1 dd ? x2 dd ? endl fistp [x2] fistp [x1] fwait mov eax,[x1] cdq idiv [x2] mov [x1],eax fild [x1] fwait ret endp proc math.imod locals x1 dd ? x2 dd ? endl fistp [x2] fistp [x1] fwait mov eax,[x1] cdq idiv [x2] mov [x1],edx fild [x1] fwait ret endp proc math.power fxch virtual at 0 jmp math.powerxy end virtual endp proc math.powerxy ftst fstsw ax fwait sahf ja .ok jb .ng .er:fstp st0 fstp st0 fldz ret .ng:fld1 fld st2 fprem fstp st1 fcomp [const_5Em16] fstsw ax fwait sahf ja .er fld st1 sub esp,4 fistp dword [esp] fwait fabs pop eax test eax,1 je .ok call .ok fchs ret .ok:fyl2x fld st0 frndint fsub st1,st0 fxch st1 f2xm1 fld1 faddp st1,st0 fscale fstp st1 ret endp proc math.pi fldpi ret endp proc math.e fld [const_e] ret endp proc math.sin fld [math.anglemode] fmulp st1,st0 fsin ret endp proc math.cos fld [math.anglemode] fmulp st1,st0 fcos ret endp proc math.tg fld [math.anglemode] fmulp st1,st0 fptan fstp st0 ret endp proc math.ctg fld [math.anglemode] fmulp st1,st0 fptan fdiv st0,st1 fstp st1 ret endp proc math.arcsin fld st0 fmul st0,st0 fld1 fsubrp st1,st0 fsqrt fpatan fld [math.anglemode] fdivp st1,st0 ret endp proc math.arccos fld st0 fmul st0,st0 fld1 fsubrp st1,st0 fsqrt fxch fpatan fld [math.anglemode] fdivp st1,st0 ret endp proc math.arctg fld1 fpatan fld [math.anglemode] fdivp st1,st0 ret endp proc math.arcctg fld1 fxch fpatan fld [math.anglemode] fdivp st1,st0 ret endp proc math.log fld1 fxch fyl2x fxch fld1 fxch fyl2x fdivp st1,st0 ret endp proc math.lg fldlg2 fxch fyl2x ret endp proc math.ln fldln2 fxch fyl2x ret endp proc math.exp fldln2 fdivp st1,st0 fld st0 frndint fsub st1,st0 fxch f2xm1 fld1 faddp st1,st0 fscale fstp st1 ret endp proc math.sqr fmul st0,st0 ret endp proc math.sqrt fsqrt ret endp proc math.abs fabs ret endp proc math.sign ftst fstsw ax fwait sahf mov eax,1 ja .end mov eax,0 jz .end dec eax .end: push eax fild dword [esp] pop eax ret endp proc math.round ; cl - argc cmp cl,1 ja .ok frndint ret .ok: fxch fld st1 fdivp st1,st0 frndint fmulp st1,st0 ret endp proc math.frac ; cl - argc cmp cl,1 ja .ok fld1 .ok: fxch fprem fstp st1 ret endp proc math.trunc ; cl - argc cmp cl,1 ja .ok fld1 .ok: fld st1 fprem fstp st1 fsubp st1,st0 ret endp proc math.min ret endp proc math.max ret endp if used const_e const_e dq 2.718281828459045 end if if used const_10 const_10 dd 10 end if if used const_5Em16 const_5Em16 dq 5E-16 end if proc RealToStr str_var locals sign dd ? dexp dd ? exp dd ? endl push edi ebx xor eax,eax mov [sign],eax mov [exp],eax mov edx,[str_var] mov eax,256 call __strsetlength mov edx,[str_var] mov edi,[edx] push edi ftst fstsw ax fwait sahf je .zero ja .positiv fchs mov [sign],1 .positiv: call math.lg ftst fstsw ax fld1 fld st1 fprem fstp st1 fsub st1,st0 fxch fwait sahf jae @f fld1 fadd st2,st0 fsubp st1,st0 @@: fistp [dexp] fild dword [const_10] fxch fld st1 call math.powerxy fadd qword [const_5Em16] fcom st1 fstsw ax fwait sahf jb @f fdiv st0,st1 inc [dexp] @@: mov edi,[esp] cmp [sign],0 je .nosign mov al,'-' stosb .nosign: mov ebx,edi add ebx,16 mov eax,[dexp] cmp eax,15 jb .g1view cmp eax,-6 jae .l1view mov [exp],eax mov [dexp],0 jmp .g1view .zero: mov al,'0' stosb jmp .noexp .l1view: mov al,'0' stosb mov al,'.' stosb mov ecx,[dexp] not ecx mov al,'0' rep stosb mov ebx,edi add ebx,15 .g1view: fld1 fld st1 fprem fstp st1 fsub st1,st0 fxch fistp [sign] fwait mov eax,[sign] add eax,'0' stosb fmul st0,st1 cmp [dexp],0 jne @f mov al,'.' stosb @@: dec [dexp] cmp edi,ebx jb .g1view fstp st0 fstp st0 @@: dec edi cmp byte [edi],'0' je @b cmp byte [edi],'.' je @f inc edi @@: cmp [exp],0 je .noexp mov al,'E' stosb mov eax,[exp] mov ebx,10 call __int2str .noexp: mov byte [edi],0 pop eax ebx edi ret endp proc StrToReal str locals sign db ? dot db ? dexp dd ? endl push esi xor ecx,ecx mov edx,ecx mov word [sign],cx mov [dexp],ecx fldz cld mov esi,[str] call __trimleft cmp al,'-' jne .loop mov [sign],1 inc esi .loop: lodsb test al,al je .end cmp al,'.' jne .nodot cmp [dot],1 je .end mov [dot],1 jmp .loop .nodot: cmp al,'E' je .exp cmp al,'e' je .exp cmp al,30h jb .end cmp al,3Ah jae .end fild dword [const_10] fmulp st1,st0 and eax,0Fh mov [esp-4],eax fild dword [esp-4] faddp st1,st0 cmp [dot],0 je .loop inc [dexp] jmp .loop .exp: lodsb test al,al je .end cmp al,'-' jne .noeminus mov ecx,1 jmp .exp .noeminus: cmp al,30h jb .end cmp al,3Ah jae .end and eax,0Fh xchg eax,edx mul byte [const_10] add edx,eax jmp .exp .end: or ecx,ecx je .noesign neg edx .noesign: sub edx,[dexp] je .nopower mov [esp-4],edx fild dword [esp-4] fild dword [const_10] call math.powerxy fmulp st1,st0 .nopower: cmp [sign],0 je .nosign fchs .nosign: fwait pop esi ret endp ; ---------------- ; MultiElementEx ; ---------------- proc MultiElementEx.Find jcxz .L2 .L1: test dword [eax],-1 jz .L2 cmp edx,[eax] jz .L2 mov eax,[eax] loop .L1 .L2: ret endp ; --------------- ; Debug support ; --------------- struct __trace.FD_SET count dd ? sock1 dd ? ends proc __debug_enumwnd hwnd,lparam invoke SetForegroundWindow,[hwnd] xor eax,eax ret endp proc __debug_timetotop x1,x2,x3,x4 invoke KillTimer,0,[__debug_timer] xor eax,eax mov [__debug_timer],eax invoke GetCurrentThreadId invoke EnumThreadWindows,eax,__debug_enumwnd,0 ret endp proc __trace,data,data.type,EID,PID,PT locals event_buf EVENTBUF set __trace.FD_SET tm TIMEVAL size dd ? cmd dd ? endl test [__trace_on],1 je .end push eax ecx edx mov eax,[__debug_timer] or eax,eax je .X0 invoke KillTimer,0,eax xor eax,eax mov [__debug_timer],eax .X0:mov eax,[data.type] mov [event_buf.type],eax mov eax,[data] mov dword [event_buf.data],eax cmp [event_buf.type],data_str jne .T1 mov edx,[data] .X1:lea eax,[event_buf.data] mov ecx,128 call __memcpy jmp .L0 .T1:cmp [event_buf.type],data_real jne .T3 mov edx,[data] cmp edx,1 jne .T2 fst qword [event_buf.data] jmp .L0 .T2:mov eax,[edx] mov dword [event_buf.data],eax mov eax,[edx+4] mov dword [event_buf.data+4],eax jmp .L0 .T3:cmp [event_buf.type],data_data jne .L0 mov edx,[data] mov eax,[edx+12] mov dword [event_buf.data],eax mov eax,[edx+8] mov [event_buf.type],eax cmp al,data_str jne .T4 mov edx,[edx+12] jmp .X1 .T4:cmp al,data_real jne .L0 add edx,12 jmp .T2 .L0:mov eax,[PID] mov [event_buf.ptid],eax mov [event_buf.cmd],3 lea eax,[event_buf] invoke sendto, [__debug_sock], eax, sizeof.EVENTBUF, 0, __dbg_cli_sockaddr, sizeof.sockaddr_in .L1:mov [set.count],1 mov eax,[__debug_sock] mov [set.sock1],eax mov [tm.tv_sec],0 mov [tm.tv_usec],500 lea eax,[set] lea edx,[tm] invoke select, 0, eax, 0, 0, edx or eax,eax je .L1 lea eax,[size] invoke ioctlsocket, [__debug_sock], FIONREAD, eax mov eax,[size] cmp eax,3 jb .L1 xor eax,eax mov [cmd],eax lea eax,[cmd] invoke recv, [__debug_sock], eax, 4, 0 mov eax,[cmd] cmp eax,1 je .L3 .L2:cmp eax,2 jne .L1 mov [__trace_on],0 .L3:mov [event_buf.cmd],4 lea eax,[event_buf] invoke sendto, [__debug_sock], eax, sizeof.EVENTBUF, 0, __dbg_cli_sockaddr, sizeof.sockaddr_in invoke SetTimer,0,0,500,__debug_timetotop mov [__debug_timer],eax pop edx ecx eax .end: ret endp ; --------------- ; GDI functions ; --------------- proc FillSolidRect hdc,x1,y1,x2,y2,color invoke SetBkColor,[hdc],[color] lea eax,[x1] invoke ExtTextOut,[hdc],0,0,ETO_OPAQUE,eax,0,0,0 ret endp proc Draw3DRect hdc,x1,y1,x2,y2,lefttop,rightbottom mov eax,[x2] dec eax mov edx,[y1] inc edx stdcall FillSolidRect,[hdc],[x1],[y1],eax,edx,[lefttop] mov eax,[x1] inc eax mov edx,[y2] dec edx stdcall FillSolidRect,[hdc],[x1],[y1],eax,edx,[lefttop] mov eax,[x2] dec eax stdcall FillSolidRect,[hdc],eax,[y1],[x2],[y2],[rightbottom] mov eax,[y2] dec eax stdcall FillSolidRect,[hdc],[x1],eax,[x2],[y2],[rightbottom] ret endp proc GetWindowPos hwnd,rect invoke GetWindowRect,[hwnd],[rect] invoke GetParent,[hwnd] or eax,eax je .exit mov edx,[rect] push eax push edx invoke ScreenToClient,eax,edx pop edx pop eax add edx,8 invoke ScreenToClient,eax,edx .exit: ret endp proc SaveBitmap hBitmap,szFileName locals hdc dd ? pBuf dd ? hFile dd ? nWr dd ? bf BMPHEADER bm BITMAP endl lea ecx,[bm] invoke GetObject,[hBitmap],sizeof.BITMAP,ecx invoke GetDC,0 mov [hdc],eax mov [bf.bi.biSize],sizeof.BITMAPINFOHEADER mov eax,[bm.bmWidth] mov [bf.bi.biWidth],eax mov eax,[bm.bmHeight] mov [bf.bi.biHeight],eax mov ax,[bm.bmPlanes] mov [bf.bi.biPlanes],ax mov [bf.bi.biBitCount],18h mov [bf.bi.biCompression],BI_RGB mov eax,[bm.bmWidth] mov ecx,3 mul ecx dec eax and eax,0FFFFFFFCh add eax,4 mul [bm.bmHeight] mov [bf.bi.biSizeImage],eax mov [bf.bi.biXPelsPerMeter],0EC4h ; 96 dpi mov [bf.bi.biYPelsPerMeter],0EC4h xor eax,eax mov [bf.bi.biClrUsed],eax mov [bf.bi.biClrImportant],eax mov [bf.fh.bfType],'BM' mov eax,[bf.bi.biSizeImage] add eax,sizeof.BITMAPFILEHEADER+sizeof.BITMAPINFOHEADER mov [bf.fh.bfSize],eax xor eax,eax mov dword [bf.fh.bfReserved1],eax mov [bf.fh.bfOffBits],sizeof.BITMAPFILEHEADER+sizeof.BITMAPINFOHEADER mov eax,[bf.bi.biSizeImage] call __alloc mov [pBuf],eax lea ecx,[bf.bi] invoke GetDIBits,[hdc],[hBitmap],0,[bm.bmHeight],eax,ecx,0 invoke CreateFile,[szFileName],GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 mov [hFile],eax lea eax,[nWr] lea ecx,[bf] invoke WriteFile,[hFile],ecx,[bf.fh.bfOffBits],eax,0 lea eax,[nWr] invoke WriteFile,[hFile],[pBuf],[bf.bi.biSizeImage],eax,0 invoke CloseHandle,[hFile] mov eax,[pBuf] call __free invoke ReleaseDC,0,[hdc] ret endp ; ----------------- ; Window contorls ; ----------------- proc FindNextTab parent_hwnd,this_tab,direction ; 0 - forwards -1 - backwards locals mintab dd ? endl push esi edi ebx mov edi,[direction] mov eax,edi not eax mov [mintab],eax xor ebx,ebx mov eax,[parent_hwnd] call .find mov eax,ebx pop ebx edi esi ret .find: invoke GetWindow,eax,GW_CHILD jmp .loope .loop: push eax invoke GetWindowLong,eax,GWL_STYLE and eax,WS_DISABLED jne .skip mov eax,[esp] invoke GetWindowLong,eax,GWL_USERDATA mov esi,eax or eax,eax je .endcmp mov eax,[pControl.hwnd] cmp eax,[esp] jne .endcmp cmp [pControl.TabOrder],0 je .endcmp cmp [direction],0 je .forw mov eax,[pControl.TabOrder] cmp edi,-1 jne .back1 cmp eax,[this_tab] jae .back1 mov edi,[this_tab] jmp .svmin .back1: cmp eax,edi jae .endcmp cmp [mintab],eax jae .endcmp jmp .svmin .forw: mov eax,[pControl.TabOrder] cmp edi,0 jne .forw1 cmp [this_tab],eax jae .forw1 mov edi,[this_tab] or edi,edi jne .svmin .forw1: cmp edi,eax jae .endcmp cmp eax,[mintab] jae .endcmp .svmin: mov [mintab],eax mov ebx,[esp] .endcmp: mov eax,[esp] call .find .skip: pop eax invoke GetWindow,eax,GW_HWNDNEXT .loope: or eax,eax jne .loop .end: retn endp proc SetWindowPosIfNeeds hwnd,hwndafter,x1,y1,wd,hg,flags locals rc RECT endl lea eax,[rc] stdcall GetWindowPos,[hwnd],eax mov edx,[x1] sub edx,[rc.left] mov eax,[y1] sub eax,[rc.top] or edx,eax mov eax,[x1] add eax,[wd] sub eax,[rc.right] or edx,eax mov eax,[y1] add eax,[hg] sub eax,[rc.bottom] or edx,eax je .exit .set: push esi invoke GetWindowLong,[hwnd],GWL_USERDATA mov esi,eax or byte [pControl.Aligning],2 invoke SetWindowPos,[hwnd],[hwndafter],[x1],[y1],[wd],[hg],[flags] and byte [pControl.Aligning],0FDh pop esi .exit: ret endp proc AlignChildWindows hwnd locals r RECT rc RECT hfirst dd ? pFlag dd ? endl push esi edi invoke GetWindow,[hwnd],GW_CHILD or eax,eax je .exit invoke GetWindow,eax,GW_HWNDLAST mov [hfirst],eax lea eax,[r] invoke GetClientRect,[hwnd],eax invoke GetWindowLong,[hwnd],GWL_USERDATA mov esi,eax lea eax,[pControl.Aligning] mov [pFlag],eax or byte [eax],1 xor eax,eax mov al,byte [pControl.Border] add [r.left],eax mov al,byte [pControl.Border+1] add [r.top],eax mov al,byte [pControl.Border+2] sub [r.right],eax mov al,byte [pControl.Border+3] sub [r.bottom],eax mov edi,(1 shl caTop)+(1 shl caBottom) call .doAlign mov edi,(1 shl caLeft)+(1 shl caRight) call .doAlign mov edi,(1 shl caClient) call .doAlign mov eax,[pFlag] and byte [eax],0FEh pop edi esi .exit: ret .doAlign: mov eax,[hfirst] .loop: mov ecx,[pFlag] test byte [ecx],1 je .exit2 or eax,eax je .exit2 push eax invoke GetWindowLong,eax,GWL_STYLE and eax,WS_VISIBLE je .skip mov eax,[esp] invoke GetWindowLong,eax,GWL_USERDATA mov esi,eax or eax,eax je .skip mov eax,[esp] lea edx,[rc] stdcall GetWindowPos,eax,edx mov cl,byte [pControl.Align] mov eax,1 shl eax,cl and eax,edi je .skip cmp cl,caLeft jne .noleft mov eax,[rc.right] sub eax,[rc.left] mov ecx,[r.bottom] sub ecx,[r.top] mov edx,[esp] mov edx,[r.left] add edx,eax push edx stdcall SetWindowPosIfNeeds,[esp+28],0,[r.left],[r.top],eax,ecx,SWP_NOZORDER pop [r.left] jmp .skip .noleft: cmp cl,caRight jne .noright mov eax,[rc.right] sub eax,[rc.left] mov ecx,[r.bottom] sub ecx,[r.top] mov edx,[esp] mov edx,[r.right] sub edx,eax push edx stdcall SetWindowPosIfNeeds,[esp+28],0,edx,[r.top],eax,ecx,SWP_NOZORDER pop [r.right] jmp .skip .noright: cmp cl,caTop jne .notop mov eax,[r.right] sub eax,[r.left] mov ecx,[rc.bottom] sub ecx,[rc.top] mov edx,[r.top] add edx,ecx push edx stdcall SetWindowPosIfNeeds,[esp+28],0,[r.left],[r.top],eax,ecx,SWP_NOZORDER pop [r.top] jmp .skip .notop: cmp cl,caBottom jne .nobottom mov eax,[r.right] sub eax,[r.left] mov ecx,[rc.bottom] sub ecx,[rc.top] mov edx,[r.bottom] sub edx,ecx push edx stdcall SetWindowPosIfNeeds,[esp+28],0,[r.left],edx,eax,ecx,SWP_NOZORDER pop [r.bottom] jmp .skip .nobottom: cmp cl,caClient jne .skip mov eax,[r.right] sub eax,[r.left] mov ecx,[r.bottom] sub ecx,[r.top] stdcall SetWindowPosIfNeeds,[esp+24],0,[r.left],[r.top],eax,ecx,SWP_NOZORDER .skip: pop eax invoke GetWindow,eax,GW_HWNDPREV jmp .loop .exit2: retn endp proc Window.WindowProc jmp dword [DefWindowProc] endp proc Control.SetColor self,color push esi mov esi,[self] mov eax,[pControl.Color] or eax,eax js @f invoke DeleteObject,[pControl.hbrush] @@: mov eax,[color] mov [pControl.Color],eax cmp eax,-1 je .transparent or eax,eax jns .colorbrush and eax,0FFh invoke GetSysColorBrush,eax jmp .savebrush .transparent: invoke GetStockObject,NULL_BRUSH jmp .savebrush .colorbrush: invoke CreateSolidBrush,eax .savebrush: mov [pControl.hbrush],eax .exit: pop esi ret endp proc Control.WindowProc hwnd,wmsg,wparam,lparam locals r RECT endl push ebx esi edi invoke GetWindowLong,[hwnd],GWL_USERDATA mov esi,eax mov eax,[pControl.ctlWP] or eax,eax je .noctlwp stdcall eax,[hwnd],[wmsg],[wparam],[lparam] or eax,eax jne .exit .noctlwp: cmp [wmsg],WM_CTLCOLORMSGBOX jb .nocolormsg cmp [wmsg],WM_CTLCOLORSTATIC ja .nocolormsg invoke GetWindowLong,[lparam],GWL_USERDATA or eax,eax je .nocolormsg push esi mov esi,eax mov eax,[pControl.TextColor] invoke SetTextColor,[wparam],eax cmp [pControl.Color],-1 je .transparent invoke SetBkMode,[wparam],OPAQUE mov eax,[pControl.Color] or eax,eax jns @f and eax,0FFh invoke GetSysColor,eax @@:invoke SetBkColor,[wparam],eax mov eax,[pControl.hbrush] pop esi jmp .exit .transparent: invoke SetBkMode,[wparam],TRANSPARENT invoke GetStockObject,NULL_BRUSH pop esi jne .exit .nocolormsg: cmp [wmsg],WM_SIZE jne .wmerasebkgnd cmp [pControl.Align],caNone je @f test byte [pControl.Aligning],2 jne @f invoke GetParent,[hwnd] or eax,eax je @f stdcall AlignChildWindows,eax @@:stdcall AlignChildWindows,[hwnd] jmp .default .wmerasebkgnd: cmp [wmsg],WM_ERASEBKGND jne .wmsetcursor cmp [pControl.Color],-1 je .default lea eax,[r] invoke GetClientRect,[hwnd],eax lea eax,[r] invoke FillRect,[wparam],eax,[pControl.hbrush] mov eax,-1 jmp .exit .wmsetcursor: cmp [wmsg],WM_SETCURSOR jne .wmnchittest cmp [pControl.Cursor],crDefault je .default cmp word [lparam],1 ;HTCLIENT jne .default invoke LoadCursor,0,[pControl.Cursor] invoke SetCursor,eax mov eax,-1 jmp .exit .wmnchittest: cmp [wmsg],WM_NCHITTEST jne .wmchar mov eax,[hoverhwnd] cmp eax,[hwnd] jne .sethover mov ecx,[pControl.HoverProc] or ecx,ecx je .default stdcall ecx,2,[lparam] jmp .default .sethover: invoke GetWindowLong,eax,GWL_USERDATA or eax,eax je .noleave push esi mov esi,eax mov ecx,[pControl.HoverProc] or ecx,ecx je @f stdcall ecx,3,[lparam] @@:pop esi .noleave: mov eax,[hwnd] mov [hoverhwnd],eax mov ecx,[pControl.HoverProc] or ecx,ecx je .default stdcall ecx,1,[lparam] jmp .default .wmchar: cmp [wmsg],WM_CHAR jne .default cmp [wparam],9 ; Tab jne .default invoke GetKeyState,VK_SHIFT and eax,8000h je @f mov eax,-1 @@: push eax mov eax,[pControl.hwnd] @@: mov edi,eax invoke GetParent,eax or eax,eax jne @b stdcall FindNextTab,edi,[pControl.TabOrder] or eax,eax je .default invoke SetFocus,eax jmp .exit .default: invoke CallWindowProc,[pControl.oldWP],[hwnd],[wmsg],[wparam],[lparam] .exit: pop edi esi ebx ret endp proc Splitter.WindowProc hwnd,wmsg,wparam,lparam locals r RECT rp RECT hdc dd ? endl push esi cmp [wmsg],WM_NCCREATE jne .nonccreate mov esi,[lparam] mov esi,[esi] invoke SetWindowLong,[hwnd],GWL_USERDATA,esi jmp .default .nonccreate: invoke GetWindowLong,[hwnd],GWL_USERDATA mov esi,eax cmp [wmsg],WM_SETCURSOR jne .nosetcursor mov ecx,[pControl.Align] mov eax,crSizeWE cmp ecx,caLeft je .hsize cmp ecx,caRight je .hsize mov eax,crSizeNS .hsize: invoke LoadCursor,0,eax invoke SetCursor,eax mov eax,-1 jmp .exit .nosetcursor: cmp [wmsg],WM_ERASEBKGND jne .noerasebkgnd lea eax,[r] invoke GetClientRect,[hwnd],eax invoke GetWindowLong,[hwnd],GWL_STYLE and eax,3 cmp eax,3 je .flat mov edx,808080h mov ecx,0FFFFFFh cmp eax,1 je @f xchg ecx,edx @@:stdcall Draw3DRect,[wparam],[r.left],[r.top],[r.right],[r.bottom],ecx,edx inc [r.left] inc [r.top] dec [r.right] dec [r.bottom] .flat: mov eax,[pControl.ColorSp] or eax,eax jns @f and eax,0FFh invoke GetSysColor,eax @@: invoke SetBkColor,[wparam],eax lea eax,[r] invoke ExtTextOut,[wparam],0,0,ETO_OPAQUE,eax,0,0,0 mov eax,-1 jmp .exit .noerasebkgnd: cmp [wmsg],WM_LBUTTONDOWN jne .nolbuttondown invoke SetCapture,[hwnd] mov eax,[lparam] mov [Splitter.startPos],eax mov [Splitter.curPos],eax call .invert jmp .exit .nolbuttondown: cmp [wmsg],WM_LBUTTONUP jne .nolbuttonup invoke GetCapture cmp eax,[hwnd] jne .default invoke ReleaseCapture mov eax,[pControl.Align] cmp eax,caLeft jne .munoleft call .limits sub ax,word [Splitter.startPos] cwde add ecx,eax jmp .mudosize .munoleft: cmp eax,caRight jne .munoright call .limits sub ax,word [Splitter.startPos] cwde sub ecx,eax jmp .mudosize .munoright: cmp eax,caTop jne .munotop call .limits shr eax,16 sub ax,word [Splitter.startPos+2] cwde add edx,eax jmp .mudosize .munotop: cmp eax,caBottom jne .exit call .limits shr eax,16 sub ax,word [Splitter.startPos+2] cwde sub edx,eax .mudosize: invoke SetWindowPos,[pControl.hwnd],0,0,0,ecx,edx,SWP_NOMOVE or SWP_NOZORDER jmp .exit .nolbuttonup: cmp [wmsg],WM_MOUSEMOVE jne .nomousemove invoke GetCapture cmp eax,[hwnd] jne .default mov eax,[Splitter.curPos] call .invert call .limits mov [Splitter.curPos],eax call .invert jmp .exit .nomousemove: cmp [wmsg],WM_CAPTURECHANGED jne .nocapturechanged mov eax,[Splitter.curPos] call .invert jmp .default .nocapturechanged: .default: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] .exit: pop esi ret .invert: push eax invoke GetDCEx,[hwnd],0,DCX_PARENTCLIP mov [hdc],eax lea eax,[r] invoke GetClientRect,[hwnd],eax mov eax,[r.right] sub eax,[r.left] mov [Splitter.size.x],eax mov eax,[r.bottom] sub eax,[r.top] mov [Splitter.size.y],eax pop eax mov edx,[Splitter.startPos] mov ecx,[pControl.Align] cmp ecx,caLeft je .hhorzsize cmp ecx,caRight je .hhorzsize shr eax,16 shr edx,16 sub ax,dx cwde add [r.top],eax add [r.bottom],eax jmp .invert2 .hhorzsize: sub ax,dx cwde add [r.left],eax add [r.right],eax .invert2: invoke SelectObject,[hdc],[Splitter.brush] push eax mov ecx,[r.right] sub ecx,[r.left] mov edx,[r.bottom] sub edx,[r.top] invoke PatBlt,[hdc],[r.left],[r.top],ecx,edx,PATINVERT pop eax invoke SelectObject,[hdc],eax invoke ReleaseDC,[hwnd],[hdc] retn .limits: invoke GetParent,[hwnd] push esi push eax lea edx,[rp] invoke GetClientRect,eax,edx pop eax invoke GetWindowLong,eax,GWL_USERDATA mov esi,eax xor eax,eax mov al,byte [pControl.Border] add [rp.left],eax mov al,byte [pControl.Border+1] add [rp.top],eax mov al,byte [pControl.Border+2] sub [rp.right],eax mov al,byte [pControl.Border+3] sub [rp.bottom],eax pop esi lea eax,[r] stdcall GetWindowPos,[pControl.hwnd],eax mov eax,[pControl.Align] cmp eax,caLeft jne .mmnoleft mov ax,[pControl.MinOwn] cwde add eax,[r.left] sub eax,[r.right] mov ecx,eax mov ax,[pControl.MinRest] cwde add eax,[Splitter.size.x] mov edx,[rp.right] sub edx,[r.right] sub edx,eax jmp .mmcmpx .mmnoleft: cmp eax,caRight jne .mmnoright mov ax,[pControl.MinRest] cwde sub eax,[r.left] add eax,[Splitter.size.x] mov ecx,eax mov ax,[pControl.MinOwn] cwde mov edx,[r.right] sub edx,[r.left] sub edx,eax jmp .mmcmpx .mmnoright: cmp eax,caTop jne .mmnotop mov ax,[pControl.MinOwn] cwde add eax,[r.top] sub eax,[r.bottom] mov ecx,eax mov ax,[pControl.MinRest] cwde add eax,[Splitter.size.y] mov edx,[rp.bottom] sub edx,[r.bottom] sub edx,eax jmp .mmcmpy .mmnotop: cmp eax,caBottom jne .mmnobottom mov ax,[pControl.MinRest] cwde sub eax,[r.top] add eax,[Splitter.size.y] mov ecx,eax mov ax,[pControl.MinOwn] cwde mov edx,[r.bottom] sub edx,[r.top] sub edx,eax .mmcmpy: mov ax,word [Splitter.startPos+2] cwde add ecx,eax add edx,eax shl ecx,16 shl edx,16 mov eax,[lparam] cmp eax,ecx jge @f mov eax,ecx @@:cmp eax,edx jl .mmdraw mov eax,edx jmp .mmdraw .mmcmpx: mov ax,word [Splitter.startPos] cwde add ecx,eax add edx,eax mov eax,[lparam] cmp ax,cx jge @f mov eax,ecx @@:cmp ax,dx jl .mmdraw mov eax,edx jmp .mmdraw .mmnobottom: mov eax,[lparam] .mmdraw: mov ecx,[r.right] sub ecx,[r.left] mov edx,[r.bottom] sub edx,[r.top] retn endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32, 'USER32.DLL',\ gdi32, 'GDI32.DLL',\ ole32, 'OLE32.DLL',\ advapi32,'ADVAPI32.DLL',\ comctl32,'COMCTL32.DLL',\ comdlg32,'COMDLG32.DLL',\ shell32, 'SHELL32.DLL',\ wsock32, 'WSOCK32.DLL' include 'INCLUDE\APIA\KERNEL32.INC' include 'INCLUDE\APIA\USER32.INC' include 'INCLUDE\APIA\GDI32.INC' include 'INCLUDE\APIA\OLE32.INC' include 'INCLUDE\APIA\ADVAPI32.INC' include 'INCLUDE\APIA\COMCTL32.INC' include 'INCLUDE\APIA\COMDLG32.INC' include 'INCLUDE\APIA\SHELL32.INC' include 'INCLUDE\APIA\WSOCK32.INC' section '.rsrc' data readable resource from __resource_file