home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / windows / modem / modemfax.pas < prev    next >
Pascal/Delphi Source File  |  1994-04-11  |  10KB  |  338 lines

  1. uses WinTypes, WinProcs, WObjects, Strings;
  2. const
  3.   idEdit     = 100;
  4.   LineWidth  = 80;  { Width of each line displayed.                  }
  5.   LineHeight = 60;  { Number of line that are held in memory.        }
  6.  
  7.   { The configuration string bellow is used to configure the modem.  }
  8.   { It is set for communication port 2, 2400 baud, No parity, 8 data }
  9.   { bits, 1 stop bit.                                                }
  10.  
  11.   Config = 'com2:24,n,8,1';
  12.  
  13.   { An example of using communication port 1, 1200 baud, Even parity }
  14.   { 7 data bits, 2 stop bits.                                        }
  15.   {  Config = 'com1:12,e,7,2';                                       }
  16.  
  17.  
  18. type
  19.   TApp = object(TApplication)
  20.     procedure Idle; virtual;
  21.     procedure InitMainWindow; virtual;
  22.     procedure MessageLoop; virtual;
  23.   end;
  24.  
  25.   PBuffer = ^TBuffer;
  26.   TBuffer = object(TCollection)
  27.     Pos: Integer;
  28.     constructor Init(AParent: PWindow);
  29.     procedure FreeItem(Item: Pointer); virtual;
  30.     function PutChar(C: Char): Boolean;
  31.   end;
  32.  
  33.   PCommWindow = ^TCommWindow;
  34.   TCommWindow = object(TWindow)
  35.     Cid: Integer;
  36.     Buffer: PBuffer;
  37.     FontRec: TLogFont;
  38.     CharHeight: Integer;
  39.     constructor Init(AParent: PWindowsObject; ATitle: PChar);
  40.     destructor Done; virtual;
  41.     procedure Error(E: Integer; C: PChar);
  42.     procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
  43.     procedure ReadChar; virtual;
  44.     procedure SetHeight;
  45.     procedure SetUpWindow; virtual;
  46.     procedure wmChar(var Message: TMessage);
  47.       virtual wm_Char;
  48.     procedure wmSize(var Message: TMessage);
  49.       virtual wm_Size;
  50.     procedure WriteChar;
  51.   end;
  52.  
  53. { TBuffer }
  54. { The Buffer is use to hold each line that is displayed in the main    }
  55. { window.  The constance LineHeight determines the number of line that }
  56. { are stored.  The Buffer is prefilled with the LineHeight worth of    }
  57. { lines.                                                               }
  58. constructor TBuffer.Init(AParent: PWindow);
  59. var
  60.   P: PChar;
  61.   I: Integer;
  62. begin
  63.   TCollection.Init(LineHeight + 1, 10);
  64.   GetMem(P, LineWidth + 1);
  65.   P[0] := #0;
  66.   Pos := 0;
  67.   Insert(P);
  68.   for I := 1 to LineHeight do
  69.   begin
  70.     GetMem(P, LineWidth + 1);
  71.     P[0] := #0;
  72.     Insert(P);
  73.   end;
  74. end;
  75.  
  76. procedure TBuffer.FreeItem(Item: Pointer);
  77. begin
  78.   FreeMem(Item, LineWidth + 1);
  79. end;
  80.  
  81. { This procedure is process all incomming in formation from the com  }
  82. { port.  This procedure is called by TCommWindow.ReadChar.           }
  83.  
  84. function TBuffer.PutChar(C: Char): Boolean;
  85. var
  86.   Width: Integer;
  87.   P: PChar;
  88. begin
  89.   PutChar := False;
  90.   Case C of
  91.     #13: Pos := 0;                          { if a Carriage Return.  }
  92.     #10:                                    { if a Line Feed.        }
  93.       begin
  94.         GetMem(P, LineWidth + 1);
  95.         FillChar(P^, LineWidth + 1, ' ');
  96.         P[Pos] := #0;
  97.         Insert(P);
  98.       end;
  99.     #8:
  100.       if Pos > 0 then                       { if a Delete.           }
  101.       begin
  102.         Dec(Pos);
  103.         P := At(Count - 1);
  104.         P[Pos] := ' ';
  105.       end;
  106.    #32..#128:                               { else handle all other  }
  107.     begin                                   { displayable characters.}
  108.       P := At(Count - 1);
  109.       Width := StrLen(P);
  110.       if Width > LineWidth then             { if line is to wide     }
  111.       begin                                 { create a new line.     }
  112.         Pos := 1;
  113.         GetMem(P, LineWidth + 1);
  114.         P[0] := C;
  115.         P[1] := #0;
  116.         Insert(P);
  117.       end
  118.       else                                   { else add character    }
  119.       begin                                  { to current line.      }
  120.         P[Pos] := C;
  121.         Inc(Pos);
  122.         P[Pos] := #0;
  123.       end;
  124.     end;
  125.   end;
  126.   if Count > LineHeight then                 { if more to many lines }
  127.   begin                                      { have been added delete}
  128.     AtFree(0);                               { current line and let  }
  129.     PutChar := True;                         { the call procedure    }
  130.   end;                                       { know to scroll up.    }
  131. end;
  132.  
  133. { TCommWindow }
  134. { The CommWindow displays the incoming and out goinging text.  There  }
  135. { should be mention that the text type by the use is displayed by     }
  136. { being echo back to the ReadChar procedure.  So there is no need for }
  137. { wmChar to write a character to the screen.                          }
  138. constructor TCommWindow.Init(AParent: PWindowsObject; ATitle: PChar);
  139. begin
  140.   TWindow.Init(AParent, ATitle);
  141.   Attr.Style := Attr.Style or ws_VScroll;
  142.   Scroller := New(PScroller, Init(@Self, 1, 1, 100, 100));
  143.   Buffer := New(PBuffer, Init(@Self));
  144. end;
  145.  
  146. { Close the Comm port and deallocate the Buffer.                      }
  147. destructor TCommWindow.Done;
  148. begin
  149.   Error(CloseComm(Cid), 'Close');
  150.   Dispose(Buffer, Done);
  151.   TWindow.Done;
  152. end;
  153.  
  154. { Checks for comm errors and writes any errors.                       }
  155. procedure TCommWindow.Error(E: Integer; C: PChar);
  156. var
  157.   S: array[0..100] of Char;
  158. begin
  159.   if E >= 0 then exit;
  160.   Str(E, S);
  161.   MessageBox(GetFocus, S, C, mb_Ok);
  162. end;
  163.  
  164. { Redraw all the lines in the buffer by using ForEach.                }
  165. procedure TCommWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  166. var
  167.   I: Integer;
  168.   Font: HFont;
  169.  
  170.   procedure WriteOut(Item: PChar); far;
  171.   begin
  172.     TextOut(PaintDC, 0, CharHeight * I, Item, StrLen(Item));
  173.     inc(I);
  174.   end;
  175.  
  176. begin
  177.   I := 0;
  178.   Font := SelectObject(PaintDC, CreateFontIndirect(FontRec));
  179.   Buffer^.ForEach(@WriteOut);
  180.   DeleteObject(SelectObject(PaintDC, Font));
  181. end;
  182.  
  183. { Read a charecter from the comm port, if there is no error then call }
  184. { Buffer^.PutChar to add it to the buffer and write it to the screen. }
  185. procedure TCommWindow.ReadChar;
  186. var
  187.   Stat: TComStat;
  188.   I, Size: Integer;
  189.   C: Char;
  190. begin
  191.   GetCommError(CID, Stat);
  192.   for I := 1 to Stat.cbInQue do
  193.   begin
  194.     Size := ReadComm(CId, @C, 1);
  195.     Error(Size, 'Read Comm');
  196.     if C <> #0 then
  197.     begin
  198.       if Buffer^.PutChar(C) then
  199.       begin
  200.         ScrollWindow(HWindow, 0, -CharHeight, Nil, Nil);
  201.         UpDateWindow(HWindow);
  202.       end;
  203.       WriteChar;
  204.     end;
  205.   end;
  206. end;
  207.  
  208. procedure TCommWindow.SetUpWindow;
  209. var
  210.   DCB: TDCB;
  211. begin
  212.   TWindow.SetUpWindow;
  213.   SetHeight;
  214.  
  215. { Open for Comm2 2400 Baud, No Parity, 8 Data Bits, 1 Stop Bit }
  216.  
  217.   BuildCommDCB(Config, DCB);
  218.   Cid := OpenComm('COM2', 1024, 1024);
  219.   Error(Cid, 'Open');
  220.   DCB.ID := CID;
  221.   Error(SetCommState(DCB), 'Set Comm State');
  222.   WriteComm(Cid, 'ATZ'#13#10, 5);  { Send a reset to Modem. }
  223. end;
  224.  
  225. { Call back function used only in to get record structure for fixed   }
  226. { width font.                                                         }
  227. function GetFont(LogFont: PLogFont; TM: PTextMetric; FontType: Word;
  228.   P: PCommWindow): Integer; export;
  229. begin
  230.   if P^.CharHeight = 0 then
  231.   begin
  232.     P^.FontRec := LogFont^;
  233.     P^.CharHeight := P^.FontRec.lfHeight;
  234.   end;
  235. end;
  236.  
  237. { Get the a fix width font to use in the TCommWindow.  Use EnumFonts  }
  238. { to save work of create the FontRec by hand.                         }
  239. { The TScroller of the main window is also updated know that the font }
  240. { height is known.                                                    }
  241. procedure TCommWindow.SetHeight;
  242. var
  243.   DC: HDC;
  244.   ProcInst: Pointer;
  245. begin
  246.   DC := GetDC(HWindow);
  247.   CharHeight := 0;
  248.   ProcInst := MakeProcInstance(@GetFont, HInstance);
  249.   EnumFonts(DC, 'Courier', ProcInst, @Self);
  250.   FreeProcInstance(ProcInst);
  251.   ReleaseDC(HWindow, DC);
  252.  
  253.   Scroller^.SetUnits(CharHeight, CharHeight);
  254.   Scroller^.SetRange(LineWidth, LineHeight);
  255.   Scroller^.ScrollTo(0, LineHeight);
  256. end;
  257.  
  258.  
  259. { Write the character from the pressed key to the Comuniction Port.   }
  260. procedure TCommWindow.wmChar(var Message: TMessage);
  261. begin
  262.   if CID <> 0 then
  263.     Error(WriteComm(CId, @Message.wParam, 1), 'Writing');
  264. end;
  265.  
  266. procedure TCommWindow.wmSize(var Message: TMessage);
  267. begin
  268.   TWindow.wmSize(Message);
  269.   Scroller^.SetRange(LineWidth, LineHeight - (Message.lParamhi div CharHeight));
  270. end;
  271.  
  272. procedure TCommWindow.WriteChar;
  273. var
  274.   DC: HDC;
  275.   Font: HFont;
  276.   S: PChar;
  277.   APos: Integer;
  278. begin
  279.   APos := Buffer^.Count - 1;
  280.   S := Buffer^.AT(APos);
  281.   APos := (APos - Scroller^.YPos) * CharHeight;
  282.   if APos < 0 then exit;
  283.   if Hwindow <> 0 then
  284.   begin
  285.     DC := GetDC(HWindow);
  286.     Font := SelectObject(DC, CreateFontIndirect(FontRec));
  287.     TextOut(DC, 0, APos, S, StrLen(S));
  288.     DeleteObject(SelectObject(DC, Font));
  289.     ReleaseDC(HWindow, DC);
  290.   end;
  291. end;
  292.  
  293. { TApp }
  294. procedure TApp.Idle;
  295. var
  296.   Stat: TComStat;
  297.   I, Size: Integer;
  298.   C: Char;
  299. begin
  300.   if MainWindow <> Nil then
  301.     if MainWindow^.HWindow <> 0 then
  302.       PCommWindow(MainWindow)^.ReadChar;
  303. end;
  304.  
  305. procedure TApp.InitMainWindow;
  306. begin
  307.   MainWindow := New(PCommWindow, Init(Nil, 'Comm Test'));
  308. end;
  309.  
  310. { Add Idle loop to main message loop.                                 }
  311. procedure TApp.MessageLoop;
  312. var
  313.   Message: TMsg;
  314. begin
  315.   while True do
  316.   begin
  317.     if PeekMessage(Message, 0, 0, 0, pm_Remove) then
  318.     begin
  319.       if Message.Message = wm_Quit then Exit;
  320.       if not ProcessAppMsg(Message) then
  321.       begin
  322.         TranslateMessage(Message);
  323.         DispatchMessage(Message);
  324.       end;
  325.     end
  326.     else
  327.       Idle;
  328.   end;
  329.   Status := Message.WParam;
  330. end;
  331.  
  332. var
  333.   App: TApp;
  334. begin
  335.   App.Init('Comm');
  336.   App.Run;
  337.   App.Done;
  338. end.