uses WinProcs, WinTypes, Win31, LEdit;
{$I LEDIT__S.INC}
{$R LEDIT_3.RES}

const
  DlgCount: integer = 0;             { Number of currently open dialogs }

var
  Buffer: array[0..3] of pointer;    { Buffer to store block pointers   }

{ Dialog function }
function  LDlgProc(Wnd:    hWnd;
		   Msg,
		   wParam: word;
		   lParam: longint): longint;
export;

var
  Pos: TLEditPosition;
  hMem: THandle;

begin
  case ( Msg ) of
    WM_INITDIALOG:
      begin
        Behaviour(GetDlgItem(Wnd,101));

	if ( DlgCount > 0) then
	  begin
	    { If this is not first dialog then fill in LEdit control     }
            { with text stored in the buffer by previous dialog-instance }
	    SendDlgItemMessage(Wnd,101,EM_SETTEXT,EMP_ALLTEXT,
	      longint(Buffer[DlgCount-1]));
          end;

        { Increase number of dialogs }
	inc(DlgCount);

        { Disable OK button if this is fourth dialog }
        EnableWindow(GetDlgItem(Wnd,IDOK),DlgCount < 4);

        { Set default focus }
	LDlgProc := 1;
        exit;
      end;
    WM_COMMAND:
      begin
	case ( wParam ) of
	  IDOK:
	    begin
              { If nothing is selected then select all the text }
	      SendDlgItemMessage(Wnd,101,EM_GETSEL,0,longint(@Pos));
	      if ( ((Pos.StartLine = Pos.EndLine) AND
         	(Pos.StartPosition = Pos.EndPosition)) ) then
		SendDlgItemMessage(Wnd,101,WM_COMMAND,EC_EDITSELECTALL,0);

              { Allocate global memory block to store selected text }
              { !!! Errors checking should be added                 }
	      Buffer[DlgCount-1] := GlobalLock(GlobalAlloc(GMEM_MOVEABLE,
		SendDlgItemMessage(Wnd,101,EM_GETSELTEXTLENGTH,0,0)+1));

              { Fill in the block with currently selected text }
	      SendDlgItemMessage(Wnd,101,EM_GETSELTEXT,0,
	        longint(Buffer[DlgCount-1]));

	      { Start new dialog-instance, which will load our text at the }
              { WM_INITDIALOG                                              }
	      DialogBox(hInstance,'DIALOG',Wnd,TFarProc(@LDlgProc));

              { Replace old text by the text supplied by dialog }
	      SendDlgItemMessage(Wnd,101,EM_REPLACESEL,0,
		longint(Buffer[DlgCount-1]));

              { Free global memory block }
	      hMem := GlobalHandle(Seg(Buffer[DlgCount-1]^));
              GlobalUnlock(hMem);
	      GlobalFree(hMem);
            end;
	  IDCANCEL:
	    begin
	      if (DlgCount > 1) then
		begin
                  { Free old memory block }
                  hMem := GlobalHandle(Seg(Buffer[DlgCount-2]^));
		  GlobalUnlock(hMem);
		  GlobalFree(hMem);

                  { Allocate new one instead with appropriate size }
		  Buffer[DlgCount-2] := GlobalLock(GlobalAlloc
		      (GMEM_MOVEABLE,SendDlgItemMessage
		      (Wnd,101,EM_GETTEXTLENGTH,EMP_ALLTEXT,0)+1));

		  { Fill in the block with text from LEdit control    }
		  { it will replace selection in the previous dialog- }
                  { instance                                          }
		  SendDlgItemMessage(Wnd,101,EM_GETTEXT,EMP_ALLTEXT,
		    longint(Buffer[DlgCount-2]));
                end;

              { Close dialog }
	      SendMessage(Wnd,WM_CLOSE,0,0);
            end;
        end;
      end;
    WM_CLOSE:
      begin
        { Decrease number of dialogs }
        dec(DlgCount);

        { End dialog }
	EndDialog(Wnd,0);
      end;
  end;
  LDlgProc := 0;
end;

{ Main block }
begin
  { Call first dialog }
  DialogBox(hInstance,'DIALOG',0,TFarProc(@LDlgProc));
end.