Diese Frage kann ich mit einem "kleinen" Codeauszug beantworten. Die Frage stammt von Dariusz Parys, der auf seinem Blog einen Aufruf dazu initiiert hat.
Der folgende Code stammt aus dem Jahr 1996 und wurde in Borland Pascal 7.0 verfasst. Sinn und Zweck der Implementierung ist es, verschiebbare Dialogfenster zu erstellen.
INTERFACE
USES CRT, REVEPRO, MOUSE, SCHIRM, DOS, CM_KEYS;
TYPE sichern = ARRAY[1..25] OF STRING[80];
farbe = ARRAY[1..25,1..80] OF BYTE;
screen = RECORD
save : sichern;
color: farbe;
END;
KFenster= RECORD
wxo,wyo,wxu,wyu: INTEGER;
END;
BFenster= RECORD
titel: STRING[80];
win_number, back_color, text_color: BYTE;
k_old, k_fenster : KFenster;
frame: BYTE;
END;
fenster = OBJECT
not_move: BOOLEAN;
dialog, old_screen: screen;
elemente: BFenster;
flag: BYTE;
aktives: POINTER;
CONSTRUCTOR INIT(element:BFenster;_actives_win : POINTER);
PROCEDURE save_back_tot;
PROCEDURE draw_win;
PROCEDURE back_total;
PROCEDURE verschieben;
PROCEDURE new_position;
PROCEDURE shadow_win;
PROCEDURE shadow_gone;
END;
VAR actives_win : POINTER;
IMPLEMENTATION
PROCEDURE fenster.save_back_tot;
VAR i,j,anfang: INTEGER;
BEGIN
HIDECURSOR;
WITH elemente.k_fenster DO
BEGIN
anfang := 0;
FOR i := 1 TO 25 DO
FOR j := 1 TO 80 DO
WITH old_screen DO
BEGIN
save[i][j] := CHR(MEM[$B800:anfang]);
INC(anfang);
color[i][j] := ORD(MEM[$B800:anfang]);
INC(anfang);
END;
END;
DISPLAYCURSOR;
END;
PROCEDURE fenster.back_total;
VAR i,j,anfang: INTEGER;
windows : ^fenster;
BEGIN
HIDECURSOR;
anfang := 0;
WITH elemente.k_fenster DO
BEGIN
FOR i := 1 TO 25 DO
FOR j := 1 TO 80 DO
WITH old_screen DO
BEGIN
MEM[$B800:anfang] := ORD(save[i][j]);
INC(anfang);
MEM[$B800:anfang] := color[i][j];
INC(anfang);
END;
END;
DISPLAYCURSOR;
actives_win := aktives;
IF actives_win <> NIL
THEN
BEGIN
windows := aktives;
windows^.elemente.frame := 205; { nicht "sauber", sorry }
windows^.draw_win;
END
ELSE
WITH elemente.k_old DO
WINDOW(wxo,wyo,wxu,wyu);
END;
PROCEDURE fenster.new_position;
VAR i,j,k: BYTE;
BEGIN
{ Verschiebe x -> rechts }
HIDECURSOR;
IF flag=1
THEN
BEGIN
{ Fenster verschieben }
FOR j := elemente.k_fenster.wyu-1 DOWNTO elemente.k_fenster.wyo-1 DO
FOR i := elemente.k_fenster.wxu-1 DOWNTO elemente.k_fenster.wxo-1 DO
BEGIN
MEM[$B800:(j*160)+((i+1)*2)] := MEM[$B800:(j*160)+(i*2)];
MEM[$B800:(j*160)+((i+1)*2)+1] := MEM[$B800:(j*160)+(i*2)+1];
END;
{ Ende Fenster verschieben }
FOR i := elemente.k_fenster.wyo-1 TO elemente.k_fenster.wyu-1 DO
BEGIN
WITH elemente.k_fenster DO
BEGIN
MEM[$B800:(i*160)+((wxo-1)*2)] := ORD(old_screen.save[i+1][wxo]);
MEM[$B800:(i*160)+((wxo-1)*2)+1] := ORD(old_screen.color[i+1][wxo])
END;
END;
INC(elemente.k_fenster.wxo);
INC(elemente.k_fenster.wxu);
END;
{ Verschiebe x -> links }
IF flag=2
THEN
BEGIN
{ Fenster verschieben }
FOR j := elemente.k_fenster.wyo-1 TO elemente.k_fenster.wyu-1 DO
FOR i := elemente.k_fenster.wxo-1 TO elemente.k_fenster.wxu DO
BEGIN
MEM[$B800:(j*160)+((i-1)*2)] := MEM[$B800:(j*160)+(i*2)];
MEM[$B800:(j*160)+((i-1)*2)+1] := MEM[$B800:(j*160)+(i*2)+1];
END;
{ Ende Fenster verschieben }
FOR i := elemente.k_fenster.wyo-1 TO elemente.k_fenster.wyu-1 DO
BEGIN
WITH elemente.k_fenster DO
BEGIN
MEM[$B800:(i*160)+((wxu-1)*2)] := ORD(old_screen.save[i+1][wxu]);
MEM[$B800:(i*160)+((wxu-1)*2)+1] := ORD(old_screen.color[i+1][wxu])
END;
END;
DEC(elemente.k_fenster.wxo);
DEC(elemente.k_fenster.wxu);
END;
{ Verschiebe y oben }
IF flag=3
THEN
BEGIN
{ Fenster verschieben }
FOR j := elemente.k_fenster.wyo-1 TO elemente.k_fenster.wyu DO
FOR i := elemente.k_fenster.wxo-1 TO elemente.k_fenster.wxu-1 DO
BEGIN
MEM[$B800:((j-1)*160)+(i*2)] := MEM[$B800:(j*160)+(i*2)];
MEM[$B800:((j-1)*160)+(i*2)+1] := MEM[$B800:(j*160)+(i*2)+1];
END;
{ Ende Fenster verschieben }
FOR i := elemente.k_fenster.wxo-1 TO elemente.k_fenster.wxu DO
BEGIN
WITH elemente.k_fenster DO
BEGIN
IF i < 80
THEN
BEGIN
MEM[$B800:((wyu-1)*160)+(i*2)] := ORD(old_screen.save[wyu][i+1]);
MEM[$B800:((wyu-1)*160)+(i*2)+1] := ORD(old_screen.color[wyu][i+1])
END;
END;
END;
DEC(elemente.k_fenster.wyo);
DEC(elemente.k_fenster.wyu);
END;
{ Verschiebe y runter }
IF flag = 4
THEN
BEGIN
{ Fenster verschieben }
FOR j := elemente.k_fenster.wyu-1 DOWNTO elemente.k_fenster.wyo-1 DO
FOR i := elemente.k_fenster.wxu-1 DOWNTO elemente.k_fenster.wxo-1 DO
BEGIN
MEM[$B800:((j+1)*160)+(i*2)] := MEM[$B800:(j*160)+(i*2)];
MEM[$B800:((j+1)*160)+(i*2)+1] := MEM[$B800:(j*160)+(i*2)+1];
END;
{ Ende Fenster verschieben }
FOR i := elemente.k_fenster.wxo-1 TO elemente.k_fenster.wxu-1 DO
BEGIN
WITH elemente.k_fenster DO
BEGIN
MEM[$B800:((wyo-1)*160)+(i*2)] := ORD(old_screen.save[wyo][i+1]);
MEM[$B800:((wyo-1)*160)+(i*2)+1] := ORD(old_screen.color[wyo][i+1])
END;
END;
INC(elemente.k_fenster.wyo);
INC(elemente.k_fenster.wyu);
END;
DISPLAYCURSOR;
END;
CONSTRUCTOR fenster.INIT(element:BFenster;_actives_win: POINTER);
VAR windows: ^fenster;
BEGIN
aktives := _actives_win;
IF aktives <> NIL
THEN
BEGIN
windows := aktives;
windows^.elemente.frame := 196; { nicht "sauber", sorry }
windows^.not_move := FALSE;
windows^.draw_win;
END;
elemente := element;
save_back_tot;
WITH elemente.k_old DO
save_ko(wxo,wyo,wxu,wyu);
not_move := TRUE;
draw_win;
END;
PROCEDURE fenster.shadow_win;
VAR i,anfang,j : INTEGER;
character: BYTE;
BEGIN
WINDOW(1,1,80,25);
WITH elemente.k_fenster DO
BEGIN
anfang := (wyu*160)+((wxo+1)*2);
IF wyu < 23
THEN
FOR i := 0 TO wxu-wxo DO
BEGIN
IF wxo+i < 79
THEN
Mem[$B800:anfang+1] := darkgray;
INC(anfang,2);
END;
FOR i := 0 TO wyu-wyo DO
BEGIN
IF wyo+i < 23
THEN
BEGIN
IF (wxu < 80)
THEN
Mem[$B800:(((wyo+i)*160)-2+((wxu+1)*2))+1] := darkgray;
IF (wxu+1 < 80)
THEN
Mem[$B800:(((wyo+i)*160)-2+((wxu+2)*2))+1] := darkgray;
END;
END;
END;
END;
PROCEDURE fenster.shadow_gone;
VAR i,anfang,j : INTEGER;
character: BYTE;
BEGIN
WINDOW(1,1,80,25);
WITH elemente.k_fenster DO
BEGIN
anfang := (wyu*160)+((wxo+1)*2);
IF wyu < 23
THEN
FOR i := wxo TO wxu DO
BEGIN
IF i < 79
THEN
Mem[$B800:anfang+1] := old_screen.color[wyu+1][i];
INC(anfang,2);
END;
FOR i := wyo TO wyu DO
BEGIN
IF i < 23
THEN
BEGIN
IF (wxu < 80)
THEN
Mem[$B800:(i*160)-2+((wxu+1)*2)+1] := old_screen.color[i+1][wxu+1];
IF (wxu+1 < 80)
THEN
Mem[$B800:(i*160)-2+((wxu+2)*2)+1] := old_screen.color[i+1][wxu+2];
END;
END;
END;
END;
PROCEDURE fenster.draw_win;
BEGIN
TEXTBACKGROUND(elemente.back_color);
TEXTCOLOR(elemente.text_color);
HIDECURSOR;
IF not_move
THEN
BEGIN
WINDOW(1,1,80,25);
WITH elemente.k_fenster DO
explode(wyo,wxo,wyu-wyo, wxu-wxo,TextAttr, DoubleBorder);
WITH elemente.k_fenster DO
WINDOW(wxo,wyo,wxu,wyu);
CLRSCR;
END;
WINDOW(1,1,80,25);
WITH elemente.k_fenster DO
zeichne(wxo,wyo,wxu,wyu,elemente.frame);
WITH elemente.k_fenster DO
GOTOXY(wxo+2,wyo);
WRITE('[ ]');
WITH elemente.k_fenster DO
GOTOXY(wxo+3,wyo);
TEXTCOLOR(green);
WRITE('þ');
TEXTCOLOR(elemente.text_color);
WITH elemente.k_fenster DO
GOTOXY(wxo+((wxu-wxo) DIV 2)-(LENGTH(elemente.titel) DIV 2),wyo);
WRITE(elemente.titel);
shadow_win;
WITH elemente.k_fenster DO
WINDOW(wxo,wyo,wxu,wyu);
DISPLAYCURSOR;
END;
PROCEDURE fenster.verschieben;
VAR mx, my, _my, _mx, ox, oy, coldx, coldy: INTEGER;
BEGIN
with_win := FALSE;
IF PRESSED=LEFT
THEN
BEGIN
IF ((( ((MAUSY DIV 8)+1 = elemente.k_fenster.wyu) AND
((MAUSX DIV 8)+1 <= elemente.k_fenster.wxu) AND
((MAUSX DIV 8)+1 >= elemente.k_fenster.wxo)) ) OR
( ((MAUSY DIV 8)+1 = elemente.k_fenster.wyo) AND
((MAUSX DIV 8)+1 <= elemente.k_fenster.wxu) AND
((MAUSX DIV 8)+1 >= elemente.k_fenster.wxo)) OR
( ((MAUSX DIV 8)+1 = elemente.k_fenster.wxu) AND
((MAUSY DIV 8)+1 <= elemente.k_fenster.wyu) AND
((MAUSY DIV 8)+1 >= elemente.k_fenster.wyo)) OR
( ((MAUSX DIV 8)+1 = elemente.k_fenster.wxo) AND
((MAUSY DIV 8)+1 <= elemente.k_fenster.wyu) AND
((MAUSY DIV 8)+1 >= elemente.k_fenster.wyo)))
AND NOT
((MAUSX DIV 8)+1-elemente.k_fenster.wxo = 3)
THEN
BEGIN
HIDECURSOR;
coldx := WHEREX;
coldy := WHEREY;
not_move := FALSE;
elemente.frame := 196;
draw_win;
shadow_gone;
ox := (MAUSX DIV 8) - elemente.k_fenster.wxo;
oy := (MAUSY DIV 8) - elemente.k_fenster.wyo;
DISPLAYCURSOR;
REPEAT
mx := MAUSX DIV 8;
my := MAUSY DIV 8;
REPEAT
_my := MAUSY DIV 8;
_mx := MAUSX DIV 8;
UNTIL (mx <> _mx) OR (my <> _my) OR (PRESSED<>LEFT);
flag := 0;
WITH elemente.k_fenster DO
BEGIN
IF (_mx > mx) AND (wxu < 80) THEN flag:=1;
IF (_my > my) AND (wyu+1 < 24) THEN flag:=4;
IF (_mx < mx) AND (wxo-1 > 0) THEN flag:=2;
IF (_my < my) AND (wyo-1 > 1) THEN flag:=3;
END;
IF flag <> 0
THEN
new_position
ELSE
BEGIN
_mx := mx;
_my := my;
END;
HideCursor;
WITH elemente.k_fenster DO
SetPos((ox+wxo)*8,(oy+wyo)*8);
DisplayCursor;
UNTIL PRESSED <> LEFT;
elemente.frame := 205;
draw_win;
not_move := TRUE;
END;
with_win := TRUE;
END;
IF (MAUSX DIV 8) = 3
THEN
BEGIN
TEXTCOLOR(green);
REPEAT
IF ((MAUSX DIV 8) = 3) AND ((MAUSY DIV 8 = 0))
THEN
BEGIN
HIDECURSOR;
GOTOXY(4,1);
WRITE(#15);
DISPLAYCURSOR;
END;
mx := MAUSX DIV 8;
my := MAUSY DIV 8;
REPEAT UNTIL (PRESSED <> LEFT) OR (mx <> MAUSX DIV 8) OR
(my <> MAUSY DIV 8);
IF ((MAUSX DIV 8) <> 3) OR ((MAUSY DIV 8 <> elemente.k_fenster.wyo))
THEN
BEGIN
HIDECURSOR;
GOTOXY(4,1);
WRITE('þ');
DISPLAYCURSOR;
END;
UNTIL PRESSED <> LEFT;
IF ((MAUSX DIV 8) = 3) AND ((MAUSY DIV 8 = 0))
THEN
event_command := cmCancel;
END;
END;
END.