home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / tpw / owldemos / fconvert.pas < prev    next >
Pascal/Delphi Source File  |  1991-05-20  |  11KB  |  387 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Pascal for Windows                     }
  4. {   Demo program                                 }
  5. {   Copyright (c) 1991 by Borland International  }
  6. {                                                }
  7. {************************************************}
  8.  
  9. program FConvert;
  10.  
  11. { This program converts text files between ANSI and OEM
  12.   character sets. The original text file is renamed to
  13.   a .BAK file and the converted file replaces the original.
  14.   DOS text files use the OEM character set; Windows text
  15.   files generally use the ANSI character set. Converting
  16.   data back and forth will only have an effect if the text
  17.   file contains international characters (ASCII values
  18.   above 128) like the umlaut, etc. Not all OEM characters
  19.   are present in the ANSI character set, and vice versa.
  20.   Therefore, converting between these character sets
  21.   may result in a loss of data. }
  22.  
  23. uses WinTypes, WinProcs, WinDos, WObjects, Strings;
  24.  
  25. {$I-,S-}
  26. {$R FCONVERT}
  27.  
  28. const
  29.  
  30. { Resource IDs }
  31.  
  32.   id_Dialog = 100;
  33.  
  34. { Convert dialog item IDs }
  35.  
  36.   id_FileName  = 100;
  37.   id_FilePath  = 101;
  38.   id_FileList  = 102;
  39.   id_DirList   = 103;
  40.   id_OemToAnsi = 104;
  41.   id_AnsiToOem = 105;
  42.   id_Convert   = 106;
  43.  
  44. { File specifier maximum length }
  45.  
  46.   fsFileSpec = fsFileName + fsExtension;
  47.  
  48. { Conversion buffer size }
  49.  
  50.   BufSize = 32768;
  51.  
  52. type
  53.  
  54. { TConvertDialog is the main window of the application. It allows
  55.   the user to select a file and convert it from the Oem to the Ansi
  56.   character set and vice versa. }
  57.  
  58.   PConvertDialog = ^TConvertDialog;
  59.   TConvertDialog = object(TDlgWindow)
  60.     FileName: array[0..fsPathName] of Char;
  61.     Extension: array[0..fsExtension] of Char;
  62.     FileSpec: array[0..fsFileSpec] of Char;
  63.     constructor Init;
  64.     procedure SetupWindow; virtual;
  65.     function GetClassName: PChar; virtual;
  66.     function GetFileName: Boolean;
  67.     procedure SelectFileName;
  68.     procedure UpdateFileName;
  69.     function UpdateListBoxes: Boolean;
  70.     procedure ConvertFile(OemToAnsi: Boolean);
  71.     procedure DoFileName(var Msg: TMessage);
  72.       virtual id_First + id_FileName;
  73.     procedure DoFileList(var Msg: TMessage);
  74.       virtual id_First + id_FileList;
  75.     procedure DoDirList(var Msg: TMessage);
  76.       virtual id_First + id_DirList;
  77.     procedure DoConvert(var Msg: TMessage);
  78.       virtual id_First + id_Convert;
  79.   end;
  80.  
  81. { TConvertApp is the application object. It creates a main window of
  82.   type TConvertDialog. }
  83.  
  84.   TConvertApp = object(TApplication)
  85.     procedure InitMainWindow; virtual;
  86.   end;
  87.  
  88. { Return a pointer to the file name part of a file path. }
  89.  
  90. function GetFileName(FilePath: PChar): PChar;
  91. var
  92.   P: PChar;
  93. begin
  94.   P := StrRScan(FilePath, '\');
  95.   if P = nil then P := StrRScan(FilePath, ':');
  96.   if P = nil then GetFileName := FilePath else GetFileName := P + 1;
  97. end;
  98.  
  99. { Return a pointer to the extension part of a file path. }
  100.  
  101. function GetExtension(FilePath: PChar): PChar;
  102. var
  103.   P: PChar;
  104. begin
  105.   P := StrScan(GetFileName(FilePath), '.');
  106.   if P = nil then GetExtension := StrEnd(FilePath) else GetExtension := P;
  107. end;
  108.  
  109. { Return True if the specified file path contains wildcards. }
  110.  
  111. function HasWildCards(FilePath: PChar): Boolean;
  112. begin
  113.   HasWildCards := (StrScan(FilePath, '*') <> nil) or
  114.     (StrScan(FilePath, '?') <> nil);
  115. end;
  116.  
  117. { Copy Source file name to Dest, changing the extension to Ext. }
  118.  
  119. function MakeFileName(Dest, Source, Ext: PChar): PChar;
  120. begin
  121.   MakeFileName := StrLCat(StrLCopy(Dest, Source,
  122.     GetExtension(Source) - Source), Ext, fsPathName);
  123. end;
  124.  
  125. { Delete a file. }
  126.  
  127. procedure FileDelete(FileName: PChar);
  128. var
  129.   F: file;
  130. begin
  131.   Assign(F, FileName);
  132.   Erase(F);
  133.   InOutRes := 0;
  134. end;
  135.  
  136. { Rename a file. }
  137.  
  138. procedure FileRename(CurName, NewName: PChar);
  139. var
  140.   F: file;
  141. begin
  142.   Assign(F, CurName);
  143.   Rename(F, NewName);
  144.   InOutRes := 0;
  145. end;
  146.  
  147. { TConvertDialog }
  148.  
  149. { Convert dialog constructor. }
  150.  
  151. constructor TConvertDialog.Init;
  152. begin
  153.   TDlgWindow.Init(nil, PChar(id_Dialog));
  154.   StrCopy(FileName, '*.*');
  155.   Extension[0] := #0;
  156. end;
  157.  
  158. { SetupWindow is called right after the Convert dialog is created.
  159.   Limit the file name edit control to 79 characters, check the Oem to
  160.   Ansi radio button, update the file and directory list boxes, and
  161.   select the file name edit control. }
  162.  
  163. procedure TConvertDialog.SetupWindow;
  164. begin
  165.   SendDlgItemMessage(HWindow, id_FileName, em_LimitText, fsPathName, 0);
  166.   CheckRadioButton(HWindow, id_OemToAnsi, id_AnsiToOem, id_OemToAnsi);
  167.   UpdateListBoxes;
  168.   SelectFileName;
  169. end;
  170.  
  171. { Return window class name. This name correspons to the class name
  172.   specified for the Convert dialog in the resource file. }
  173.  
  174. function TConvertDialog.GetClassName: PChar;
  175. begin
  176.   GetClassName := 'ConvertDialog';
  177. end;
  178.  
  179. { Return True if the name in the file name edit control is not a
  180.   directory and does not contain wildcards. Otherwise, update the
  181.   file and directory list boxes as required. }
  182.  
  183. function TConvertDialog.GetFileName: Boolean;
  184. var
  185.   FileLen: Word;
  186. begin
  187.   GetFileName := False;
  188.   GetDlgItemText(HWindow, id_FileName, FileName, fsPathName + 1);
  189.   FileExpand(FileName, FileName);
  190.   FileLen := StrLen(FileName);
  191.   if (FileName[FileLen - 1] = '\') or HasWildCards(FileName) or
  192.     (GetFocus = GetDlgItem(HWindow, id_DirList)) then
  193.   begin
  194.     if FileName[FileLen - 1] = '\' then
  195.       StrLCat(FileName, FileSpec, fsPathName);
  196.     if not UpdateListBoxes then
  197.     begin
  198.       MessageBeep(0);
  199.       SelectFileName;
  200.     end;
  201.     Exit;
  202.   end;
  203.   StrLCat(StrLCat(FileName, '\', fsPathName), FileSpec, fsPathName);
  204.   if UpdateListBoxes then Exit;
  205.   FileName[FileLen] := #0;
  206.   if GetExtension(FileName)[0] = #0 then
  207.     StrLCat(FileName, Extension, fsPathName);
  208.   AnsiLower(FileName);
  209.   GetFileName := True;
  210. end;
  211.  
  212. { Select the file name edit control. }
  213.  
  214. procedure TConvertDialog.SelectFileName;
  215. begin
  216.   SendDlgItemMessage(HWindow, id_FileName, em_SetSel, 0, $7FFF0000);
  217.   SetFocus(GetDlgItem(HWindow, id_FileName));
  218. end;
  219.  
  220. { Update the file name edit control. }
  221.  
  222. procedure TConvertDialog.UpdateFileName;
  223. begin
  224.   SetDlgItemText(HWindow, id_FileName, AnsiLower(FileName));
  225.   SendDlgItemMessage(HWindow, id_FileName, em_SetSel, 0, $7FFF0000);
  226. end;
  227.  
  228. { Update the file and directory list boxes. }
  229.  
  230. function TConvertDialog.UpdateListBoxes: Boolean;
  231. var
  232.   Result: Integer;
  233.   Path: array[0..fsFileName] of Char;
  234. begin
  235.   UpdateListBoxes := False;
  236.   if DlgDirList(HWindow, FileName, id_FileList, id_FilePath, 0) <> 0 then
  237.   begin
  238.     DlgDirList(HWindow, '*.*', id_DirList, 0, $C010);
  239.     StrLCopy(FileSpec, FileName, fsFileSpec);
  240.     UpdateFileName;
  241.     UpdateListBoxes := True;
  242.   end;
  243. end;
  244.  
  245. { Convert file from Oem to Ansi or from Ansi to Oem. }
  246.  
  247. procedure TConvertDialog.ConvertFile(OemToAnsi: Boolean);
  248. var
  249.   N: Word;
  250.   L: Longint;
  251.   Buffer: Pointer;
  252.   TempName, BakName: array[0..fsPathName] of Char;
  253.   InputFile, OutputFile: file;
  254.  
  255.   function Error(Stop: Boolean; Message: PChar): Boolean;
  256.   begin
  257.     if Stop then
  258.     begin
  259.       if Buffer <> nil then FreeMem(Buffer, BufSize);
  260.       if TFileRec(InputFile).Mode <> fmClosed then Close(InputFile);
  261.       if TFileRec(OutputFile).Mode <> fmClosed then
  262.       begin
  263.         Close(OutputFile);
  264.         Erase(OutputFile);
  265.       end;
  266.       InOutRes := 0;
  267.       MessageBox(HWindow, Message, 'Error', mb_IconStop + mb_Ok);
  268.     end;
  269.     Error := Stop;
  270.   end;
  271.  
  272. begin
  273.   MakeFileName(TempName, FileName, '.$$$');
  274.   Assign(InputFile, FileName);
  275.   Assign(OutputFile, TempName);
  276.   Buffer := MemAlloc(BufSize);
  277.   if Error(Buffer = nil, 'Not enough memory for copy buffer.') then Exit;
  278.   Reset(InputFile, 1);
  279.   if Error(IOResult <> 0, 'Cannot open input file.') then Exit;
  280.   Rewrite(OutputFile, 1);
  281.   if Error(IOResult <> 0, 'Cannot create output file.') then Exit;
  282.   L := FileSize(InputFile);
  283.   while L > 0 do
  284.   begin
  285.     if L > BufSize then N := BufSize else N := L;
  286.     BlockRead(InputFile, Buffer^, N);
  287.     if Error(IOResult <> 0, 'Error reading input file.') then Exit;
  288.     if OemToAnsi then
  289.       OemToAnsiBuff(Buffer, Buffer, N) else
  290.       AnsiToOemBuff(Buffer, Buffer, N);
  291.     BlockWrite(OutputFile, Buffer^, N);
  292.     if Error(IOResult <> 0, 'Error writing output file.') then Exit;
  293.     Dec(L, N);
  294.   end;
  295.   FreeMem(Buffer, BufSize);
  296.   Close(InputFile);
  297.   Close(OutputFile);
  298.   MakeFileName(BakName, FileName, '.bak');
  299.   FileDelete(BakName);
  300.   FileRename(FileName, BakName);
  301.   FileRename(TempName, FileName);
  302. end;
  303.  
  304. { File name edit control response method. }
  305.  
  306. procedure TConvertDialog.DoFileName(var Msg: TMessage);
  307. begin
  308.   if Msg.LParamHi = en_Change then
  309.     EnableWindow(GetDlgItem(HWindow, id_Convert),
  310.       SendMessage(Msg.LParamLo, wm_GetTextLength, 0, 0) <> 0);
  311. end;
  312.  
  313. { File list box response method. }
  314.  
  315. procedure TConvertDialog.DoFileList(var Msg: TMessage);
  316. begin
  317.   case Msg.LParamHi of
  318.     lbn_SelChange, lbn_DblClk:
  319.       begin
  320.         DlgDirSelect(HWindow, FileName, id_FileList);
  321.         UpdateFileName;
  322.         if Msg.LParamHi = lbn_DblClk then DoConvert(Msg);
  323.       end;
  324.     lbn_KillFocus:
  325.       SendMessage(Msg.LParamLo, lb_SetCurSel, Word(-1), 0);
  326.   end;
  327. end;
  328.  
  329. { Directory list box response method. }
  330.  
  331. procedure TConvertDialog.DoDirList(var Msg: TMessage);
  332. begin
  333.   case Msg.LParamHi of
  334.     lbn_SelChange, lbn_DblClk:
  335.       begin
  336.         DlgDirSelect(HWindow, FileName, id_DirList);
  337.         StrCat(FileName, FileSpec);
  338.         if Msg.LParamHi = lbn_DblClk then
  339.           UpdateListBoxes else
  340.           UpdateFileName;
  341.       end;
  342.     lbn_KillFocus:
  343.       SendMessage(Msg.LParamLo, lb_SetCurSel, Word(-1), 0);
  344.   end;
  345. end;
  346.  
  347. { Convert button response method. }
  348.  
  349. procedure TConvertDialog.DoConvert(var Msg: TMessage);
  350. var
  351.   OemToAnsi: Boolean;
  352.   P: array[0..1] of PChar;
  353.   S: array[0..127] of Char;
  354. begin
  355.   if not GetFileName then Exit;
  356.   OemToAnsi := IsDlgButtonChecked(HWindow, id_OemToAnsi) <> 0;
  357.   P[0] := FileName;
  358.   if OemToAnsi then P[1] := 'Oem to Ansi' else P[1] := 'Ansi to Oem';
  359.   WVSPrintF(S, 'Convert %s from %s character set?  ' +
  360.     'Warning: this mapping may be irreversible!', P);
  361.   if MessageBox(HWindow, S, 'Convert',
  362.     mb_IconStop + mb_YesNo + mb_DefButton2) <> id_Yes then Exit;
  363.   ConvertFile(OemToAnsi);
  364.   WVSPrintF(S, 'Done with conversion of %s (a .BAK file was created).', P);
  365.   MessageBox(HWindow, S, 'Success', mb_IconInformation + mb_Ok);
  366.   UpdateListBoxes;
  367.   SelectFileName;
  368. end;
  369.  
  370. { TConvertApp }
  371.  
  372. { Create a Convert dialog as the application's main window. }
  373.  
  374. procedure TConvertApp.InitMainWindow;
  375. begin
  376.   MainWindow := New(PConvertDialog, Init);
  377. end;
  378.  
  379. var
  380.   ConvertApp: TConvertApp;
  381.  
  382. begin
  383.   ConvertApp.Init('ConvertApp');
  384.   ConvertApp.Run;
  385.   ConvertApp.Done;
  386. end.
  387.