theraphy
asked on
Ms-dos similar console type applications
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
thanx
ASKER
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...
Hmm. The application IS a windows application. You can call win32 functions and you can't call such a console program in dos mode...
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) !
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) !
tothpaul, that's what I said, isn't it???
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.
ASKER
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....
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.
ASKER
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... ?
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,ccIn tens);
TConColors = set of TConColor;
var
Cd: TCoord;
hOutput,hInput: hWnd;
c: char;
S: String[10];
fgc,bgc: TConColors;
{$R *.RES}
function GetNextKey(ConsoleInputHan dle: 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(ConsoleOutputhand le: 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(Co nsoleOutpu thandle,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_HA NDLE);
hInput := GetStdHandle(STD_INPUT_HAN DLE );
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(h Output,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
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,ccIn
TConColors = set of TConColor;
var
Cd: TCoord;
hOutput,hInput: hWnd;
c: char;
S: String[10];
fgc,bgc: TConColors;
{$R *.RES}
function GetNextKey(ConsoleInputHan
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(ConsoleOutputhand
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(Co
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_HA
hInput := GetStdHandle(STD_INPUT_HAN
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(h
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
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
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
I'll be da...
Forgot, that you cannot use the Showmessage then :-) ..replace it with:
Cd.X:= 0;
Cd.Y:= 7;
SetConsoleCursorPosition(h Output,Cd) ;
WriteLn('Username: '+S);
Write('<Press a key to exit>');
c:= GetNextKey(hInput);
Forgot, that you cannot use the Showmessage then :-) ..replace it with:
Cd.X:= 0;
Cd.Y:= 7;
SetConsoleCursorPosition(h
WriteLn('Username: '+S);
Write('<Press a key to exit>');
c:= GetNextKey(hInput);
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
Look at my CrtSock unit, Pascal TextFiles can be used to read from/write to anything !
Regards
Paul TOTH
http://www.multimania.com/tothpaul
ASKER
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...
ASKER
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...
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
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
ASKER
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.
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.
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.
Regards, Madshi.
ASKER
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...
?- 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...
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(Old EditWndPro c),hwnd,ms g,182,0);
result:=CallWindowProc(poi nter(OldEd itWndProc) ,hwnd,msg, wparam,lpa ram);
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(Old EditWndPro c),hwnd,ms g,183,0);
edit.selAttributes.color:= clNavy;
exit;
end else if (wParam<256) and (chr(wParam) in [#9,#13,#32..#126,#128,#14 5,#167,#17 6,#178..#1 81,#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(poi nter(OldEd itWndProc) ,hwnd,msg, wparam,lpa ram);
end;
procedure HookRichEdit;
begin
with edit.font do begin size:=12; name:='Courier New'; color:=clNavy end;
OldEditWndProc:=SetWindowL ong(edit.h andle,GWL_ WNDPROC,in teger(@Edi tHookProc) );
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... :-)
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:=
CallWindowProc(pointer(Old
result:=CallWindowProc(poi
edit.selAttributes.color:=
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:=
CallWindowProc(pointer(Old
edit.selAttributes.color:=
exit;
end else if (wParam<256) and (chr(wParam) in [#9,#13,#32..#126,#128,#14
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(poi
end;
procedure HookRichEdit;
begin
with edit.font do begin size:=12; name:='Courier New'; color:=clNavy end;
OldEditWndProc:=SetWindowL
end;
Just make a new project, add a RichEdit component on it, put it into the edit variable ("edit:=form1.richEdit1"),
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... :-)
ASKER
YES... THAT'S IT THANX MADSHI :-))))
now let me give you 100 points...
regards...
now let me give you 100 points...
regards...
ASKER
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_GETTEXTLENGT H, 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(Old EditWndPro c),hwnd,ms g,wparam,l param);
exit;
end else exit;
WM_KEYUP : exit;
WM_CHAR : if wParam=VK_RETURN then begin
result:=CallWindowProc(poi nter(OldEd itWndProc) ,hwnd,msg, wparam,lpa ram);
if (inputtext <> '') and (inputtext[length(inputtex t)] = '.') then
begin
// after this point process the command and
// display the answer, again scroll down one line
// CallWindowProc(pointer(Old EditWndPro c),hwnd,ms g,13,0);
// display the command line prompt
CallWindowProc(pointer(Old EditWndPro c),hwnd,ms g,63,0);
CallWindowProc(pointer(Old EditWndPro c),hwnd,ms g,150,0);
CallWindowProc(pointer(Old EditWndPro c),hwnd,ms g,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(Old EditWndPro c),hwnd,ms g,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(poi nter(OldEd itWndProc) ,hwnd,msg, wparam,lpa ram);
end;
procedure HookRichEdit;
begin
with edit.font do begin
size:=10;
name:='Courier New';
color:=clNavy
end;
OldEditWndProc:=SetWindowL ong(edit.h andle,GWL_ WNDPROC,in teger(@Edi tHookProc) );
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
edit := richedit1;
// display the commnd line prompt
sendmessage(richedit1.hand le, wm_char, 63, 0);
sendmessage(richedit1.hand le, wm_char, 150, 0);
sendmessage(richedit1.hand le, wm_char, 32, 0);
hookrichedit;
end;
thanx again.. :-)
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_GETTEXTLENGT
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(Old
exit;
end else exit;
WM_KEYUP : exit;
WM_CHAR : if wParam=VK_RETURN then begin
result:=CallWindowProc(poi
if (inputtext <> '') and (inputtext[length(inputtex
begin
// after this point process the command and
// display the answer, again scroll down one line
// CallWindowProc(pointer(Old
// display the command line prompt
CallWindowProc(pointer(Old
CallWindowProc(pointer(Old
CallWindowProc(pointer(Old
// 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..
CallWindowProc(pointer(Old
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(poi
end;
procedure HookRichEdit;
begin
with edit.font do begin
size:=10;
name:='Courier New';
color:=clNavy
end;
OldEditWndProc:=SetWindowL
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
edit := richedit1;
// display the commnd line prompt
sendmessage(richedit1.hand
sendmessage(richedit1.hand
sendmessage(richedit1.hand
hookrichedit;
end;
thanx again.. :-)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Check it, it should be would you need.
Regards, Madshi.