Solved

Ms-dos similar console type applications

Posted on 1999-01-05
23
235 Views
Last Modified: 2010-04-04
I want to develop an application that uses a console type interface for user input like ms-dos prompt but it must run under windows not under dos so i don't want to use the conditinal define of compiler that compiles the program as a dos console type application. and i do not want to use tmemo for user input.

thanx
0
Comment
Question by:theraphy
  • 9
  • 6
  • 4
  • +2
23 Comments
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
If you look at the project options, page "Linker". There's a checkbox named "console application" or "textmode application" (I've the german version, so I can't tell you the exact name).
Check it, it should be would you need.

Regards, Madshi.
0
 

Author Comment

by:theraphy
Comment Utility
Thanx madshi but this is not what i need... when you check that it generates a dos based application... i need a WINDOWS application which got a console form that behaves like ms-dos promt... for that i creted a timage and aligned it alclient and i wrote some code to form's onkeydown event for displaying the keys pressed on timage but this not give the result i need... because it has no cursor which is blinking...
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Hmm. The application IS a windows application. You can call win32 functions and you can't call such a console program in dos mode...
0
 

Expert Comment

by:tothpaul
Comment Utility
a "console application" run only under windows 32 bits !
You can also use AllocConsole API in a GUI application to open a text mode window (still a 32bits application).

To run under DOS a console application need a 32bits DOS extender like WDOSX (freeware) !
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
tothpaul, that's what I said, isn't it???
0
 
LVL 5

Expert Comment

by:heathprovost
Comment Utility
Madshi is correct.  Delphi CANNOT (without some serious modifications anyway) create DOS applications.  A console app under delphi is a Win32 console, which is the same thing as what you would end up with using tothpaul's method.  Now if you want a console INTERFACE to do some kind of custom command line processing without spawning a real console, that would be something entirely different.  Is this what you are trying to do?  Please clarify.
0
 

Author Comment

by:theraphy
Comment Utility
sorry tothpaul as i said in my question i do not want that kind of solution... may be it is my fault i couldn't tell what i need but at least healthprovost understood what i am asking for... thanx healthprovost... yes i want a console interface....
0
 
LVL 5

Expert Comment

by:heathprovost
Comment Utility
What you are attempting to do is unfortunately quite involved if you were to write all the code yourself.  There is however a component on the Delphi Super Page called TConsole (and TColorConsole) which should do what you want.  The filename is consol.zip.  It is probably on other Delphi sites as well.  If a component solution is not sufficient please respond so we can explore other options.
0
 

Author Comment

by:theraphy
Comment Utility
thanx heathprovost... that is the ting i need but now i got problems using it... because it is not well documantated and i can not get any user input (like readln operation in pascal)... i've studied its source code and it is a little bit complex for me... :-( what do you think about developing a new component from tcustomedit... ?
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
I actually think this thread became kind of interesting. So I did some developing, and I thought this example might become usable (Though you have to hardcode most of things due to a lack of console interfaces)

The example processes user input from the keyboard, but can also be built to accept any other kind of events.

Just Make a new project and remove the unit from the project manager and the paste this to the project source:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Dialogs,
  Windows,
  Forms;

Type
  TConColor = (ccBlue,ccGreen,ccRed,ccIntens);
  TConColors = set of TConColor;

var
  Cd: TCoord;
  hOutput,hInput: hWnd;
  c: char;
  S: String[10];
  fgc,bgc: TConColors;

{$R *.RES}

   function GetNextKey(ConsoleInputHandle: hWnd): Char;
   var
     IRec: TInputRecord;
     count: Integer;
   begin
     Result:= #0;
     Repeat
       ReadConsoleInput( hInput, IRec, 1, count);
       If IRec.EventType = KEY_EVENT then
       If IRec.KeyEvent.bKeyDown then Result:= IRec.KeyEvent.AsciiChar;
     until Result<>#0;
   End;

   procedure SetColor(ConsoleOutputhandle: hWnd; fgColor,bgColor: TConColors);
   var
     C: WORD;
   begin
     C:= 0;
     If ccBlue   in fgColor then C:= C OR FOREGROUND_BLUE;
     If ccGreen  in fgColor then C:= C OR FOREGROUND_GREEN;
     If ccred    in fgColor then C:= C OR FOREGROUND_RED;
     If ccIntens in fgColor then C:= C OR FOREGROUND_INTENSITY;
     If ccBlue   in bgColor then C:= C OR BACKGROUND_BLUE;
     If ccGreen  in bgColor then C:= C OR BACKGROUND_GREEN;
     If ccred    in bgColor then C:= C OR BACKGROUND_RED;
     If ccIntens in bgColor then C:= C OR BACKGROUND_INTENSITY;
     SetConsoleTextAttribute(ConsoleOutputhandle,C);
   End;

   procedure WriteChars(code,count: Integer);
   Begin
     While count>0 do
     begin
       Write(chr(code));
       Dec(count);
     End;
   End;

begin
  fgc:= [ccRed,ccGreen,ccBlue];
  bgc:= [ccGreen];

  hOutput:= GetStdHandle(STD_OUTPUT_HANDLE);
  hInput := GetStdHandle(STD_INPUT_HANDLE );

  SetColor(hOutput,fgc,bgc);

  WriteChars(177,39); Writeln(#177);
  WriteChars(177,40); Writeln(#0);
  WriteChars(177,9);

  Exclude(bgc,ccGreen);
  SetColor(hOutput,fgc,bgc);
  Write(' Username:');
  WriteChars(32,12);

  Include(bgc,ccGreen);
  SetColor(hOutput,fgc,bgc);
  WriteChars(177,9);  Writeln(#0);
  WriteChars(177,40); Writeln(#0);
  WriteChars(177,40); Writeln(#0);

  Exclude(bgc,ccGreen);
  SetColor(hOutput,fgc,bgc);
  SetColor(hOutput,fgc,bgc);
  Write(#32);

  Include(bgc,ccGreen);
  SetColor(hOutput,fgc,bgc);
  WriteChars(32,40);
  Exclude(bgc,ccGreen);
  SetColor(hOutput,fgc,bgc);

  Cd.X:= 20;
  Cd.Y:= 2;

  SetConsoleCursorPosition(hOutput,Cd);

  Repeat
    c:= GetNextKey(hInput);
    If (c=#8) AND (S<>'') then
    Begin
      Delete(S,Length(S),1);
      write(#8#0#8);
    End else
    If (ord(c)>31) AND (Length(S)<10) then
    Begin
      S:= S + C;
      write(c);
    End;
  Until c = #13; //User pressed return

  ShowMessage('Username: '+S);
end.

Regards,
Williams
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
Ok, I really don't know what you want when you say you don't want to generate a console application, but anyhow I find the example quite funny

sorry another thing, just write:

uses
  Windows;

instead of all the other stuff in the uses clause, and your compiled program will only take up 17 Kb. :-)

Cheers,
Williams
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 3

Expert Comment

by:williams2
Comment Utility
I'll be da...

Forgot, that you cannot use the Showmessage then :-) ..replace it with:

  Cd.X:= 0;
  Cd.Y:= 7;
  SetConsoleCursorPosition(hOutput,Cd);
  WriteLn('Username: '+S);
  Write('<Press a key to exit>');
  c:= GetNextKey(hInput);
0
 

Expert Comment

by:tothpaul
Comment Utility
Okay ! you can also use WINCRT Unit !

Look at my CrtSock unit, Pascal TextFiles can be used to read from/write to anything !

Regards
Paul TOTH
http://www.multimania.com/tothpaul

0
 

Author Comment

by:theraphy
Comment Utility
tothpaul where can ifind wincrt unit? and some information about it? i looked at delphi help but tere's nothimg about it and added it uses clause and delphi generated an error because of not finding it...
0
 

Author Comment

by:theraphy
Comment Utility
tothpaul i've found and used wincrt unit it again does not provide what i need.. as heatprovost said i need a console type interface...
0
 
LVL 3

Expert Comment

by:williams2
Comment Utility
have you testet my example ? ..is it something like this you are looking for ?

Then I guess you will find it a bit difficult to find. You can ask yourself how many are interested in coding a complete console Interface with windowed controls under windows 95/98/NT? ..But anyway, it can be done like the way I described OR by using Borland Turbo PASCAL, but that's 16bit of course :-(

Cheers,
Williams
0
 

Author Comment

by:theraphy
Comment Utility
thanx williams2 but this is not i need.

what i am exactly trying to do is developing an ai based programming language and for this reason the language development environment needs a console type interface which prompts program outputs and gets user commands. just like the one in amzi prolog listener.
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Then please tell me what's wrong with my first suggestion? I still think it is what you need. IT IS NO DOS PROGRAM, BUT A REAL WIN32 BIT CONSOLE PROGRAM!

Regards, Madshi.
0
 

Author Comment

by:theraphy
Comment Utility
ok madshi it is awin32 bit console program and IT IS A PROGRAM... i need a component just like a tmemo. let me tell you my program interface. first of all it is not a mdi application. it got three sections one of them is editor section, one of them is messages section and the last one is console section. all of them are displayed on tpanel and have splitters between them. so when the user enters the console section the user can give some specific commands to compile program into memory or etc. it looks like this :

?- consult(myprogram).
yes.

the "?-" is command line prompt... and "yes" is the respond of the program..


with your suggest i can only develop a console type PROGRAM.... but i need a console type interface to use with other visual components...

thanx anyway...

0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Ahhh - now I understand it...  :-)

If you don't find a component that is good enough, you could do it yourself. I would suggest using a TRichEdit (because there you can easily use different colors for input and output). Unfortunately I have not the time to implement a ready-to-use component for you, but this should help you (I hope):

var OldEditWndProc : integer;
    edit           : TRichEdit;
    inputText      : string;

function EditHookProc(hwnd, msg,wparam,lparam: integer) : integer; stdcall;
begin
  result:=0;
  case msg of
    WM_SETTEXT, WM_GETTEXT, WM_GETTEXTLENGTH, WM_COPYDATA, WM_CUT, WM_COPY, WM_PASTE, WM_CLEAR, WM_DDE_FIRST..WM_DDE_LAST : exit;
    WM_KEYDOWN, WM_KEYUP : exit;
    WM_CHAR              : if wParam=VK_BACK then begin
                             exit;
                           end else if wParam=VK_RETURN then begin
                             // here you can fire an ReadLn event with "inputText"...
                             edit.selAttributes.color:=clBlack;
                             CallWindowProc(pointer(OldEditWndProc),hwnd,msg,182,0);
                             result:=CallWindowProc(pointer(OldEditWndProc),hwnd,msg,wparam,lparam);
                             edit.selAttributes.color:=clNavy;
                             inputText:='';
                             exit;
                           end else if wParam=VK_TAB then begin
                             beep;
                             exit;
                           end else if wParam=VK_SPACE then begin
                             inputText:=inputText+#32;
                             edit.selAttributes.color:=clBlack;
                             CallWindowProc(pointer(OldEditWndProc),hwnd,msg,183,0);
                             edit.selAttributes.color:=clNavy;
                             exit;
                           end else if (wParam<256) and (chr(wParam) in [#9,#13,#32..#126,#128,#145,#167,#176,#178..#181,#192..#255]) then begin
                             inputText:=inputText+#32;
                             exit;
                           end else exit;
    WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, WM_RBUTTONDOWN, WM_RBUTTONUP,
    WM_RBUTTONDBLCLK, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MBUTTONDBLCLK, WM_MOUSEWHEEL : exit;
  end;
  result:=CallWindowProc(pointer(OldEditWndProc),hwnd,msg,wparam,lparam);
end;

procedure HookRichEdit;
begin
  with edit.font do begin size:=12; name:='Courier New'; color:=clNavy end;
  OldEditWndProc:=SetWindowLong(edit.handle,GWL_WNDPROC,integer(@EditHookProc));
end;

Just make a new project, add a RichEdit component on it, put it into the edit variable ("edit:=form1.richEdit1"), call HookRichEdit and run it.

Surely you'll have to make some (perhaps a lot?) of changes, but I hope you understand how it works...

Regards, Madshi.

P.S: I copied it (and changed it a little bit) from one of my sources, so it does some strange things. Don't get confused because of that...   :-)
0
 

Author Comment

by:theraphy
Comment Utility
YES... THAT'S IT THANX MADSHI :-))))

now let me give you 100 points...

regards...
0
 

Author Comment

by:theraphy
Comment Utility
by the way madshi this is the modified version of your solution as you see i only did a few minor changes...
var
  OldEditWndProc : integer;
  edit           : TRichEdit;
  inputText      : string;

function EditHookProc(hwnd, msg,wparam,lparam: integer) : integer; stdcall;
begin
  result := 0;
  case msg of
    WM_SETTEXT, WM_GETTEXT,WM_GETTEXTLENGTH, WM_COPYDATA, WM_CUT,
    WM_COPY, WM_PASTE, WM_CLEAR,
    WM_DDE_FIRST..WM_DDE_LAST : exit;

    WM_KEYDOWN : if wparam in [vk_left, vk_right, vk_down, vk_up, vk_back] then
                 begin
                   result := CallWindowProc(pointer(OldEditWndProc),hwnd,msg,wparam,lparam);
                   exit;
                 end else exit;

    WM_KEYUP : exit;

    WM_CHAR : if wParam=VK_RETURN then begin
                result:=CallWindowProc(pointer(OldEditWndProc),hwnd,msg,wparam,lparam);
                if (inputtext <> '') and (inputtext[length(inputtext)] = '.') then
                begin
                  // after this point process the command and
                  // display the answer, again scroll down one line
                  // CallWindowProc(pointer(OldEditWndProc),hwnd,msg,13,0);
                  // display the command line prompt
                  CallWindowProc(pointer(OldEditWndProc),hwnd,msg,63,0);
                  CallWindowProc(pointer(OldEditWndProc),hwnd,msg,150,0);
                  CallWindowProc(pointer(OldEditWndProc),hwnd,msg,32,0);
                  // and then initialize input text :-> inputText:='';
                end;
                exit;
              end else if wParam=VK_TAB then begin
                beep;
                exit;
             end else if (wParam<256) and (chr(wParam) in [#32..#126,
             #128,#145,#167,#176,#178..#181,#192..#255]) then begin
                CallWindowProc(pointer(OldEditWndProc),hwnd,msg,wparam,0);
                inputText:=inputText + chr(wparam);
                exit;
              end else exit;

    WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK,
    WM_RBUTTONDOWN, WM_RBUTTONUP, WM_RBUTTONDBLCLK, WM_MBUTTONDOWN,
    WM_MBUTTONUP, WM_MBUTTONDBLCLK, WM_MOUSEWHEEL : exit;
  end;
  result:=CallWindowProc(pointer(OldEditWndProc),hwnd,msg,wparam,lparam);
end;

procedure HookRichEdit;
begin
  with edit.font do begin
    size:=10;
    name:='Courier New';
    color:=clNavy
  end;
  OldEditWndProc:=SetWindowLong(edit.handle,GWL_WNDPROC,integer(@EditHookProc));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  edit := richedit1;
  // display the commnd line prompt
  sendmessage(richedit1.handle, wm_char, 63, 0);
  sendmessage(richedit1.handle, wm_char, 150, 0);
  sendmessage(richedit1.handle, wm_char, 32, 0);
  hookrichedit;
end;

thanx again.. :-)
0
 
LVL 20

Accepted Solution

by:
Madshi earned 100 total points
Comment Utility
I'm just glad that I could help you...  :-)

Thanx for the points.  :-)

Regards, Madshi.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now