Lazarus

Programming => General => Topic started by: Paolo on November 28, 2020, 03:00:36 pm

Title: [Solved] dos program
Post by: Paolo on November 28, 2020, 03:00:36 pm
Hello,

I need help for a very old code (TP3 and DOS, maybe recompiled in TP6, I don%u2019t remember)

I was able to porting it in Lazarus (Laz.2.0.10, FPC 3.2.0) on Win 10 por -64 bit, and it basically works.

Two things I wasn%u2019t able to solve:

1)   The program uses %u201Cgraphical output%u201D and at the start the program opens 2 windows (in DOS mode), the first one can accept keyboard input and the second one is for the graphical program (the only one I expect to have !). This seems that implies keyboard input cannot received by the %u201Cgraphic windows%u201D, but it works fine if I insert input on the on the first windows. I need to input directly on the graphic window%u201D!
2)   I have in my old code the %u201Cinterrupt%u201D  approach to handle of mouse input. I removed such routines, but how to manage mouse inputs in the %u201Cgraphical windows%u201D ?

In the figure (fig.1 and fig.2) the two input windows side by side (I need only the graphical one), I was able, in the old version, to use different cursor and selecting and moving elements of graphical window.

The program should work reading just one char (the capital one in the command menu)

attached the most relevant code (if needed I can post more) for comment (but complete alternative to do the job are welcome)


Code: Pascal  [Select][+][-]
  1.  
  2. USES  Dos,Crt,Graph,GraphPV,UO;
  3.  
  4. CONST  ESC = #27;
  5.        ENDWORK = 10;
  6.  
  7. (****************************** MAIN ***************************************)
  8.  
  9. Begin
  10.   InizializzaGrafica(1);
  11.   IF (GraphResult <> GrOK) Then Begin
  12.     Write('Sorry, no VGA, Bye-Bye ! ');
  13.     Readln;
  14.     Halt;
  15.   End;
  16.   Presentation;    //just show the "LOGO" an wait for "ReaLn;" to go on
  17.   SetScreen;       //here start the Graph code
  18.   Repeat
  19.     ProcessInput;  //wait for input/action user -> here I need:
  20.                    //                              1) to work on the graphical windows
  21.                    //                              2) mouse usage on the graphical windows
  22.   Until (Stop = ENDWORK);
  23.   CloseGraph;
  24. End.
  25.  
  26. where
  27.  
  28. Procedure InizializzaGrafica(a:Word);
  29.  
  30. var g1,g2:smallInt;
  31.  
  32. Begin
  33.  Case a OF
  34.  0:Begin g1:=Detect; End;
  35.  1:Begin g1:=Vga; g2:=VgaHi; End;
  36.  2:Begin g1:=Vga; g2:=VgaMed; End;
  37.  End;
  38.  initgraph(g1,g2,'');
  39. End;
  40.  
  41.  
  42. PROCEDURE ProcessInput;        (* *)
  43.  
  44. Begin
  45.   InputMouseKeyb;
  46.   Case Stop OF
  47.     0:
  48.     Begin
  49.  
  50.     End;
  51.     1:
  52.     Begin
  53.       Case InpKey OF
  54.         ESC:
  55.         Begin
  56.           Stop:=ENDWORK;
  57.         End;
  58.         'N','n':
  59.         Begin
  60.           IF (LastZero <= MaxRadici) Then
  61.           Begin
  62.             Inc(LastZero);
  63.             NewZero;
  64.           End
  65.           Else
  66. (* ? *)     MessagWin(' Raggiunto il max Numero di Zeri ');
  67.         End;
  68.         'O','o':
  69.         Begin
  70.           LastZero:=NumeroElementi;
  71.           OrchPencil;
  72.         End;
  73.         'M','m':
  74.         Begin
  75.           Select;
  76.         End;
  77.         'D','d':
  78.         Begin
  79.           RemoveZero;
  80.         End;
  81.         'C','c':
  82.         Begin
  83.           ComputingFunction;
  84.         End;
  85.         'R','r':
  86.         Begin
  87.           SetFillStyle(SolidFill,Black);
  88.           Bar(Bordo1,Bordo1,MaxXScreen-Bordo1,MaxYScreen-Bordo2);
  89.           SetScreen;
  90.           SetFillStyle(SolidFill,Blue);
  91.         End;
  92.         'E','e':
  93.         Begin
  94.           NewCommand;
  95.           ManipulateZero;
  96.           MainCommand;
  97.         End;
  98.         'p','P':
  99.         Begin
  100.           SetFillStyle(SolidFill,Black);
  101.           Bar(20,20,200,200);
  102.         End;
  103.       End;
  104.     End;
  105.     2:
  106.     Begin
  107.  
  108.     End;
  109.     3:
  110.     Begin
  111.       Stop:=ENDWORK;
  112.     End;
  113.   End;
  114. End;
  115.  
  116. PROCEDURE InputMouseKeyb;         (* lettura dell'input *)
  117.  
  118. Begin
  119.   Stop:=-1;
  120.   Repeat
  121.     IF KeyPressed Then
  122.     Begin
  123.       InpKey:=ReadKey;
  124.       IF InpKey = #0 Then
  125.       Begin
  126.         InpKey:=ReadKey;
  127.         Stop:=0;
  128.       End
  129.       Else
  130.         Stop:=1;
  131.     End
  132.     Else
  133.     Begin
  134.     End;
  135.   Until (Stop >= 0) AND (Stop <= 3);
  136. End;
  137.  
  138.  
  139.  
Title: Re: dos program
Post by: PascalDragon on November 28, 2020, 03:52:45 pm
In the figure (fig.1 and fig.2) the two input windows side by side (I need only the graphical one), I was able, in the old version, to use different cursor and selecting and moving elements of graphical window.

You can try to use PtcCrt and PtcGraph instead of Crt and Graph. Though you might need to adjust colors (or the loading/saving of images).
Title: Re: dos program
Post by: Paolo on November 28, 2020, 04:05:57 pm
thanks,

but changing to PtcCrt e PtcGraph the program after showing the first dos windows crashes !

Quote
Though you might need to adjust colors (or the loading/saving of images)

Are you saying that the attached picture of bad quality ? I can see both without problem.
Title: Re: dos program
Post by: Paolo on November 28, 2020, 04:19:17 pm
added PtcGraph also to my unit GraphPV, now there is an exception at the execution, if I ignore the graphical window accept the char inputs, but still two windows !

the error was "the project raised the exception TPCTError : cannot recycle because it is not already open";

but for the mouse functionality ?

Title: Re: dos program
Post by: lucamar on November 28, 2020, 04:20:02 pm
Are you saying that the attached picture of bad quality ? I can see both without problem.

No, he means that PtcGraph color definitions might not be entirely compatible with those in Graph.
Title: Re: dos program
Post by: rvk on November 28, 2020, 04:20:36 pm
1)   The program uses “graphical output” and at the start the program opens 2 windows (in DOS mode), the first one can accept keyboard input and the second one is for the graphical program (the only one I expect to have !). This seems that implies keyboard input cannot received by the “graphic windows”, but it works fine if I insert input on the on the first windows. I need to input directly on the graphic window”!
You have a console application. So that second (actually the first) is a console window.
If you don't want a console window you can enable gui application.
Goto Project > Project Options > Compiler Options > Config and Target
and set the checkmark at "Win32 gui application" (or compile with -WG option).
Title: Re: dos program
Post by: lucamar on November 28, 2020, 04:37:02 pm
You have a console application. So that second (actually the first) is a console window.
If you don't want a console window you can enable gui application.

Actually, he seems to have two console windows; only the second one is in "graphic" mode*. As to how he did that ... it's anyone guess :o

Interactions and quirks in such a  program (or, really, in any DOS graphics program) are so complicated that I won't comment more without seeing all the code, but if were you (the OP) I would just convert it to a GUI application and spare myself lots of grief ;)


* Yes, I know both are really in graphics mode, but bear with me, OK? 8)
Title: Re: dos program
Post by: rvk on November 28, 2020, 04:57:00 pm
You have a console application. So that second (actually the first) is a console window.
If you don't want a console window you can enable gui application.
Actually, he seems to have two console windows; only the second one is in "graphic" mode*. As to how he did that ... it's anyone guess :o
The graphic window is opened by the initgraph call.
So it isn't really a console window (like the default one). The default console windows is a text-window. The second one is graphic.

But I agree. Using a real Windows-window and using a canvas would be much simpler. Especially when dealing with mouse-events.
Title: Re: dos program
Post by: PascalDragon on November 28, 2020, 05:13:59 pm
You have a console application. So that second (actually the first) is a console window.
If you don't want a console window you can enable gui application.

Actually, he seems to have two console windows; only the second one is in "graphic" mode*. As to how he did that ... it's anyone guess :o

No, the Graph unit on Windows opens a normal GUI window, but you have the console window nevertheless.

But I agree. Using a real Windows-window and using a canvas would be much simpler. Especially when dealing with mouse-events.

The Graph unit creates a real Windows-window on Windows. ;)

added PtcGraph also to my unit GraphPV, now there is an exception at the execution, if I ignore the graphical window accept the char inputs, but still two windows !

the error was "the project raised the exception TPCTError : cannot recycle because it is not already open";

Well, PTC is not a fully compatible drop-in replacement, so some adjustments need to be made.

but for the mouse functionality ?

You need to take a look at PtcMouse if you continue to use PTC.
Title: Re: dos program
Post by: Paolo on November 28, 2020, 05:42:51 pm
thanks to all,

@rvk
yes, I did , I have a very nice application on windows that fully replace the one discussing here. I want just to try to recover the old-style-code.
By your suggestion I still have the exception raised but apparently I can work (after removing one readln;) with the graphical windows alone (even if maybe at the begin the dos-window flashes)

@lucamar
 yes, I see two "windows"

@PascalDragon
yes, I'll check the PTCMouse.

However, soon I'll post here the minimal code to reproduce the effect I see (it is quite easy, very few raws of code)
In DOS the orignal progam works in this way (it was a demo for univesity student in the engineering faculty)
- start
- open a "Logo" windows
- wait for "Readln;" to move on
- start the graphical interface
- here just typing a letter a command is executed or..
- ..by mouse I can select some element and move it around in the final position

I soon as possible I'll post here the minimal code to reproduce what is happening.

Title: Re: dos program
Post by: PascalDragon on November 28, 2020, 07:42:12 pm
However, soon I'll post here the minimal code to reproduce the effect I see (it is quite easy, very few raws of code)
In DOS the orignal progam works in this way (it was a demo for univesity student in the engineering faculty)
- start
- open a "Logo" windows
- wait for "Readln;" to move on
- start the graphical interface
- here just typing a letter a command is executed or..
- ..by mouse I can select some element and move it around in the final position

I soon as possible I'll post here the minimal code to reproduce what is happening.

The problem is that Graph programs can't be translated 1:1 to modern, graphical OSes, because the terminal emulators these OSes provide can't be used in a graphical mode like they could be on DOS. There'll always be some problem like there being two windows on Windows because there's the terminal window due to it being a console application and the graphic window it creates to do the actual graphic stuff.
Title: Re: dos program
Post by: Paolo on November 28, 2020, 08:08:01 pm
@PascalDragon

I suspect that you are right,

but as last tentative, here the project (first version, no @PascalDrang and @avk suggestion implemented, almost all the code removed)
it complies and run, but to move on with keyboard inoput you must come back on the console window (activate and insert there).
First do "enter" to quit "Presentation" routine, then the only char of keyboard that show somthing, to have visual effect, are: "O","R","E","ESC", but again they must given in the console windows
Title: Re: dos program
Post by: Mr.Madguy on November 29, 2020, 11:37:25 am
I guess, you have the same problem, as I had with my BmpView program. It's console application, as in DOS applications are console ones. They just switch video card to graphic mode, but DOS supports console input/output even in graphic mode. Only HX can provide some degree of Win GUI emulation. Other DOS extenders usually don't. So, it uses console input. But on Windows you need to create window for graphical output. It's not forbidden for Win console applications to create windows. But it's separate second window.

Only solution - is to make input driver. It should use console input on DOS, but window input on Windows. Unfortunately HX application still needs to be console, as HX tries to emulate Win GUI via switching to 32bit VBE 2.0 mode, if application is GUI. And that can fail, if video card doesn't support that mode. My solution - is to hide console window via getting console HWND via GetConsoleWindow (if it's supported) and calling ShowWindow with SW_HIDE for it. That's how my program works.

My program is in attachment. Picture.bmp is removed, as archive should be <500Kb. Any 24bit bmp file without compression can be used for this purpose.

Console.drv - is console input driver.
Windows.drv - is combined Windows graphic/input driver.

But of course I use custom graphic library Graph32.dll and custom input library Keyb32.dll. Pascal Graph library should be modified to provide access to it's window, so you would be able to add input handling to it.
Title: Re: dos program
Post by: Paolo on November 29, 2020, 11:51:28 am
Thanks madguy.
I understood that in your workaround console windows is still there and I need keyboardinput. Do you have some code to show ?
Following the suggestion of rvk, and removing the intermediate readln; all works fine, I jump in the online graphical (no console window or maybe it is hidden  ) windows and accepting char input command, however this approach raises the exception I cited above, I need to intercept it and just ignore. I'll double check later if this works on release mode.
As already comment it is just a tentative to resume a dead code full rewritten now  as standard windows application.
Title: Re: dos program
Post by: Mr.Madguy on November 29, 2020, 12:02:23 pm
Thanks madguy.
I understood that in your workaround console windows is still there and I need keyboardinput. Do you have some code to show ?
Following the suggestion of rvk, and removing the intermediate readln; all works fine, I jump in the online graphical (no console window or maybe it is hidden  ) windows and accepting char input command, however this approach raises the exception I cited above, I need to intercept it and just ignore. I'll double check later if this works on release mode.
As already comment it is just a tentative to resume a dead code full rewritten now  as standard windows application.
I guess, suggestions above are right. You just need Graph and Crt modifications, that support Windows. I've never used PtcGraph/PtcCrt, but, I guess, it's right suggestion. You just need to do two things: 1) Switch application type to GUI, so console window will disappear 2) Find a reason, why it throws exception. According to exception text, you try to use something before initializing it properly.
Title: Re: dos program
Post by: nickysn on December 01, 2020, 05:01:45 am
Hi, I'm the author of ptcgraph, ptccrt, ptcmouse and ptcpas. If you want keyboard input to work with ptcgraph, you should use ptccrt and only 'readkey' and 'keypressed', not read/readln. Keyboard input via read/readln is not supported while the graphics window is open. And if you want to get rid of the console window, add {$apptype gui} to your program.
Title: Re: dos program
Post by: Paolo on December 01, 2020, 01:47:44 pm
Thanks a lot nickysn,
I'll try yor suggestions as soon as possible.
Title: Re: dos program
Post by: Paolo on December 01, 2020, 08:01:47 pm
@nicksyn

now with readkey it is fine, there is still the error raiseed in initgraph : "the project raised the exception TPCTError : cannot recycle because it is not already open" do you know how to avoid this ?

thanks again.
Title: Re: dos program
Post by: nickysn on December 02, 2020, 05:01:18 am
Can you give me a small example program and the exact specs to reproduce the "cannot recycle because it is not already open" error? Which Windows version are you using? What is the graphics card?
Title: Re: dos program
Post by: Paolo on December 02, 2020, 11:15:19 am
Yes, I'll attach the sample test later.

Laz 2.0.10, fpc 3.2.0, win 10 pro, graphic card gtx-1030.
Title: Re: dos program
Post by: Paolo on December 02, 2020, 08:54:43 pm
the file
Title: Re: dos program
Post by: Paolo on December 05, 2020, 12:10:25 pm
Dear nicksyn,

I am using "GetMouseState(Posizione.PosX, Posizione.PosY, buttype);" to retrive the mouse position and button state.
What I see is that once a click is done ButType returns a value in the range 1..3, but how can I RESET the buttype ? succcessive calla to GetMouseState still give buttype = last click, also LPressed seems anchored to the last click event.

Can you give me an idea how this works ?

thanks
Title: Re: dos program
Post by: nickysn on December 05, 2020, 05:20:27 pm
These only give you the current state of the buttons. Note that "buttype" in your example is actually a bit mask, and it's not necessarily in the range 1..3, but can actually be in the range 0..7. Each binary bit indicates the state of an individual button:

     bit 1 set -> left button pressed
     bit 2 set -> right button pressed
     bit 3 set -> middle button pressed

To check whether the left button is currently pressed:

if (buttype and 1) <> 0 then
begin
  // left button is currently pressed
end;
if (buttype and 2) <> 0 then
begin
  // right button is currently pressed
end;
if (buttype and 4) <> 0 then
begin
  // middle button is currently pressed
end;

To get the moment that left mouse button is clicked only once, you need to keep the previous button state, and catch the moment, where the left mouse button is pressed now, but wasn't pressed the previous time. E.g.

lastbuttype := 0;
repeat  // loop start
  GetMouseState(Posizione.PosX, Posizione.PosY, buttype);
  if ((buttype and 1) <> 0) and ((lastbuttype and 1) = 0) then
  begin
    // on left mouse button click...
  end;
  if ((buttype and 2) <> 0) and ((lastbuttype and 2) = 0) then
  begin
    // on right mouse button click...
  end;
  if ((buttype and 4) <> 0) and ((lastbuttype and 4) = 0) then
  begin
    // on middle mouse button click...
  end;

  // do other stuff here

  lastbuttype := buttype;
until false; // loop end
Title: Re: dos program
Post by: nickysn on December 05, 2020, 05:23:39 pm
Note also that the following constants are defined in ptcmouse for convenience, when using the bit mask:

const
  LButton = 1; { left button   }
  RButton = 2; { right button  }
  MButton = 4; { middle button }

so instead of

if (buttype and 4) <> 0 then

you can use

if (buttype and MButton) <> 0 then
Title: Re: dos program
Post by: Paolo on December 05, 2020, 06:05:33 pm
perfect !

many thanks, something to re-code but now it works !

PS: still the error message at begin, did you find the cause ?
Title: Re: dos program
Post by: nickysn on December 05, 2020, 07:19:41 pm
Didn't have time today to check it, sorry, but I'll try to find some time tomorrow.
Title: Re: dos program
Post by: Paolo on December 05, 2020, 07:51:28 pm
many thanks again.

In my old version of the software I was also able to change the cursor shape, is it still possbile ?
Title: Re: dos program
Post by: nickysn on December 07, 2020, 11:22:07 pm
No, unfortunately, it's not possible to change the cursor, but you can hide the regular cursor, using HideCursor and draw your own cursor manually. After you're done, you can use ShowCursor to show the normal cursor again.

The exception you get on startup, when running the program with the Lazarus debugger is normal, and not propagated to your program. It's an exception that is raised internally and then caught and handled all inside the ptc library code. The Lazarus debugger by default catches all exceptions,as soon as they are raised, and not just *unhandled* exceptions. In this case, this is an annoyance, and should be disabled by unchecking 'Notify on Exceptions' inside Tools->Options->Debugger->Language Exceptions.

Also note that you don't need to handle any exceptions in your code, so the try..except block around InitGraph is not needed. This is really not an exception that is propagated to your code, it's just caught by the debugger, because of the 'Notify on Exceptions' option. As you can see, your program runs just fine, when run outside the debugger, and that is also the case, when you remove the try..except block as well.
Title: Re: dos program
Post by: Paolo on December 08, 2020, 12:06:06 am
Thanks a lot,
I am very happy to see my old code working again. That wasn't possibile without your help.
I see that the exception is only in the IDE.
Concerning the mouse you said that I need to draw it by myself, are you suggesting something like (in sequence) :
1) draw a cursor
2) catch new mouse position
3) delete cursor at old position
4) draw cursor at new position
... and so on.
Right ?
Title: Re: dos program
Post by: nickysn on December 08, 2020, 07:47:06 am
Yes, something like that.
TinyPortal © 2005-2018