для текстового режима (консоль или командная сторка DOS) написал я виджет "однострочное поле ввода" там суть алгоритма сводится к тому что есть 3 основных параметра base - смещение 1го отображаемого pointer - смещение с курсором counter всего символов в строке и дополнительные координаты размер и прочее логика алгоритма - как только курсор выходит из отрезка [base, base+frame_size] корретируется значение base и курсор остается на своем месте у границы кто нить писал чтонить аналогичное но только многострочное? идеи по поводу вычисления длины фрагмента если там символы перехода на наовую строку ? может мануал кто встречал??? нехочется особо тяжелую логику реализовывать - аля глифы и все такое
ну, насколько я вижу из неприведённого кода, с переносом посреди пакета придётся дела иметь как раз таки посредством сложной логики .)
Comer_ код привести не проблема только он у меня 16 разрядный под дос и сколько кода привести - только код компонента или поноценной маленькой программы ???
вот фрагментик ответственный за вывод поля без учета символов разрыва строки Код (Text): ;=======[ SUBROUTINE ]============================ ; Write field text ;------------------------------------------------- ; Parameters: ; DS:SI - seg:ofs(Widget) @Activity\; 0FFh is active, 000h is passive = -08h ;------------------------------------------------- @Routine_private\ Fld_Write_Text push BX push CX push DX push AX ;----------------------------------------- mov CX,(Widget PTR [SI])\ .Widget_Total stc jcxz $exit call Fld_Get_Capacity mul AH mov DX,AX mov BX,(Widget PTR [SI])\ .Widget_Arrow sub BX,(Widget PTR [SI])\ .Widget_Base jc $less cmp BX,DX jae $greater jmp\ short $tail ;----------------------------------------- $less: add (Widget PTR [SI])\ .Widget_Base,BX mov AX,BX jmp\ short $tail ;----------------------------------------- $greater: mov AX,BX sub AX,DX inc AX add (Widget PTR [SI])\ .Widget_Base,AX ;----------------------------------------- $tail: mov CX,DX $loop: push [BP+@Activity] mov AX,DX sub AX,CX push AX push (Widget PTR [SI])\ .Widget_Total push (Widget PTR [SI])\ .Widget_Arrow push (Widget PTR [SI])\ .Widget_Base mov AX,(Widget PTR [SI])\ .Widget_Coords push AX call Fld_Write_Tail loop $loop clc ;----------------------------------------- $exit: pop AX pop DX pop CX pop BX @Routine_end ;=======[ SUBROUTINE ]============================ ; Write tail ;------------------------------------------------- ; Parameters: ; DS:SI - seg:ofs(widget) @Activity\ = 0Eh @Ordinal\ = 0Ch @Total\ = 0Ah @Arrow\ = 8 @Base\ = 6 @Coords\ = 4 ;------------------------------------------------- @Routine_private\; my macro of std prologue Fld_Write_Tail push DS push ES push SI push DI push CX push DX ;----------------------------------------- call Fld_Seek_Style ;----------------------------------------- mov AX,ES:(Field PTR [DI])\ .Field_Symbol_Quantity or AL,AL jz $exit or AH,AH jz $exit ;----------------------------------------- lds SI,(Widget PTR [SI])\ .Widget_Stuff_Address mov AX,ES:(Field PTR [DI])\ .Field_Coords add [BP+@Coords],AL add [BP+@Coords]+1,AH ;----------------------------------------- mov AX,[BP+@Ordinal] div ES: BYTE PTR (Field PTR [DI])\ .Field_Symbol_Quantity xchg AL,AH add AL,[BP+@Coords] add AH,[BP+@Coords]+1 ;----------------------------------------- IF @Alone @P_Locate\ AX @Call_far\ field_dso,@Set_AX_Coords_ID ELSE @Locate\ AX ENDIF ;----------------------------------------- mov DX,[BP+@Ordinal] add DX,[BP+@Base] mov CX,[BP+@Activity] jcxz $passive cmp DX,[BP+@Arrow] jne $active call ES:(Field PTR [DI])\ .Field_Method_Cursor; set cur coord ;----------------------------------------- $active: mov AX,CS:Field_Palette xchg AL,AH jmp\ short $color $passive: mov AX,CS:Field_Palette ;----------------------------------------- IF @Alone @P_Color\ AX,Color @Call_far\ field_dso,@Set_Color_ID @Call_far\ field_affix,@Measure_String_ID ELSE @Color call Measure_String ENDIF ;----------------------------------------- inc AX cmp AX,[BP+@Total] jbe $inside mov AX,[BP+@Total] ;----------------------------------------- $inside: cmp DX,AX jae $space add SI,DX lodsb or AL,AL jnz $write ;----------------------------------------- $space: mov AL,ES:(Field PTR [DI])\ .Field_Space_Symbol ;----------------------------------------- $write: IF @Alone @P_Out_One\ AL @Call_far\ field_dso,@Out_AL_Symbol_ID ELSE @Out_One ENDIF ;----------------------------------------- $exit: pop DX pop CX pop DI pop SI pop ES pop DS @Routine_end 0Ch