home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l040 / 11.ddi / OWLDEMOS.ZIP / FCONVERT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-27  |  10.9 KB  |  394 lines

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