Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.10.2014, 11:01
OSIRIS OSIRIS вне форума
Прохожий
 
Регистрация: 04.01.2008
Сообщения: 11
Репутация: 10
По умолчанию нид хелп (командная строка в мемо)

ситуация следующая:
есть консольное приложение, после запуска надо в него предавать данные и считывать результат соответственно

перекопал много чего - рабочего примера так и не нашел

самое близкое - исходники redirect-a ( http://vovan-ve.fatal.ru/download/55 )
но там проблема с кодировкой

пробовал

компонент RusCod1 - не помогло

функции
Код:
function StrOemToAnsi(const S: AnsiString): AnsiString;
begin
  SetLength(Result, Length(S));
  OemToAnsiBuff(@S[1], @Result[1], Length(S));
end;

//---------------------------------------------------------------
function StrAnsiToOem(const S: AnsiString): AnsiString;
begin
  SetLength(Result, Length(S));
  AnsiToOemBuff(@S[1], @Result[1], Length(S));
end;
Админ: Пользуемся тегами для оформления кода!

тоже не спасают

PS:
Embarcadero® RAD Studio XE 2010
Windows 7 проф.

Последний раз редактировалось Admin, 02.10.2014 в 19:20.
Ответить с цитированием
  #2  
Старый 03.10.2014, 09:45
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от OSIRIS
функции
Код:
function StrOemToAnsi(const S: AnsiString): AnsiString;
begin
  SetLength(Result, Length(S));
  OemToAnsiBuff(@S[1], @Result[1], Length(S));
end;

//---------------------------------------------------------------
function StrAnsiToOem(const S: AnsiString): AnsiString;
begin
  SetLength(Result, Length(S));
  AnsiToOemBuff(@S[1], @Result[1], Length(S));
end;

тоже не спасают
Вот так должно работать:
Код:
function CharToOemCase(Value: AnsiString): AnsiString;
begin
  Result := Value;
  if Result <> '' then CharToOemBuffA(Pointer(Result), Pointer(Result), Length(Result));
end;

function OemToCharCase(Value: AnsiString): AnsiString;
begin
  Result := Value;
  if Result <> '' then OemToCharBuffA(Pointer(Result), Pointer(Result), Length(Result))
end;
Пример:
Код:
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows;

function CharToOemCase(Value: AnsiString): AnsiString;
begin
  Result := Value;
  if Result <> '' then CharToOemBuffA(Pointer(Result), Pointer(Result), Length(Result));
end;

function OemToCharCase(Value: AnsiString): AnsiString;
begin
  Result := Value;
  if Result <> '' then OemToCharBuffA(Pointer(Result), Pointer(Result), Length(Result))
end;

begin
  Writeln(CharToOemCase('Проверка'));
  Readln;
end.
Ответить с цитированием
  #3  
Старый 03.10.2014, 17:07
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Гадостью CharToOem лучше не пользоваться, она корежит символы псевдографики. Для современных версий Delphi правильным будет решение через встроенные преобразования UnicodeString:
Код:
type
  OEMString = type AnsiString(CP_OEMCP);
var
  S: OEMString;
  U: UnicodeString;
begin
  ReadLn(RedirOut, S);
  U := S;
  Memo1.Add(U);
end;
По идее, должно сработать и прямое присваивание, поскольку OEMString физически тоже UnicodeString:
Код:
begin
  ReadLn(RedirOut, S);
  Memo1.Add(S);
end;
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #4  
Старый 08.10.2014, 10:40
OSIRIS OSIRIS вне форума
Прохожий
 
Регистрация: 04.01.2008
Сообщения: 11
Репутация: 10
По умолчанию

заработал вот такой код:
Код:
function StrAnsiToOem(const S: String): AnsiString;
begin
  SetLength(Result, Length(S)*2);
  AnsiToOemBuff(@S[1], @Result[1], Length(S)*2);
end;

function StrOemToAnsi(const S: String): AnsiString;
begin
  SetLength(Result, Length(S)*2);
  OemToAnsiBuff(@S[1], @Result[1], Length(S)*2);
end;

прием работает нормально, по крайней мере при старте ( запускается консольное приложение и выдает данные в подобающем виде)
однако при попытке отправить команду ничего не происходит, а при нажатии "end write" команда вроде отправляется - однако обрезается по ходу дела до 1 символа
исправленные исходники могу приложить или выложить какую либо часть кода
Ответить с цитированием
  #5  
Старый 08.10.2014, 13:09
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от OSIRIS
при нажатии "end write" команда вроде отправляется - однако обрезается по ходу дела до 1 символа
Аффтар, ты баран. Пользоваться Юникод-версией Delphi и городить какую-то кривую самопальщину вместо встроенного преобразования кодовых страниц -- надо быть альтернативно одаренным. Неужели нельзя справку почитать? Есть прекрасная функция SetCodePage. Передавай ей GetOEMCP, и будет тебе преобразование из кодовой страницы OEM.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #6  
Старый 08.10.2014, 15:09
OSIRIS OSIRIS вне форума
Прохожий
 
Регистрация: 04.01.2008
Сообщения: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от Freeman
Аффтар, ты баран. Пользоваться Юникод-версией Delphi и городить какую-то кривую самопальщину вместо встроенного преобразования кодовых страниц -- надо быть альтернативно одаренным. Неужели нельзя справку почитать? Есть прекрасная функция SetCodePage. Передавай ей GetOEMCP, и будет тебе преобразование из кодовой страницы OEM.

"setcodepage" надо будет запомнить, ранее не натыкался, вопрос же сейчас уже по больше части в другом - почему не идет отправка данных в консольное приложение, или же оно идет но не полностью?

к слову говоря:
Код:
procedure TForm1.btnWriteClick(Sender: TObject);
var s:string;
begin
    if zRedirect<>nil then begin
        s := edInput.Text+#13#10;
        if rgCharset.ItemIndex=1 then
            //CharToOem(@s[1],@s[1]);   //////////
            s:=StrAnsiToOem(s);
        zRedirect.WriteData(s);
        edInput.Text := '';
    end;
end;

procedure TRedirectThread.WriteData(Data: string);
var writen:Cardinal;
begin
    if (hWriteIn<>0) and (Length(Data)>0) then begin
        WriteFile(hWriteIn, Data[1], Length(Data), writen, nil);
    end;
end;
Ответить с цитированием
  #7  
Старый 08.10.2014, 15:57
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

По-нормальному должно быть как-то так:
Код:
procedure TForm1.btnWriteClick(Sender: TObject);
var
  s: string;
begin
  if zRedirect <> nil then
  begin
    s := edInput.Text + sLineBreak;
    if rgCharset.ItemIndex = 1 then
      SetCodePage(s, GetOEMCP, True);
    zRedirect.WriteData(s);
    edInput.Text := '';
  end;
end;

procedure TRedirectThread.WriteData(Data: RawByteString); // переопределил!
var
  Written: Cardinal;
begin
  if hWriteIn <> 0 then
    WriteFile(hWriteIn, Data[1], Length(Data) * StringElementSize(Data), Written, nil);
end;
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #8  
Старый 08.10.2014, 16:11
OSIRIS OSIRIS вне форума
Прохожий
 
Регистрация: 04.01.2008
Сообщения: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от Freeman
По-нормальному должно быть как-то так:
Код:
procedure TForm1.btnWriteClick(Sender: TObject);
var
  s: string;
begin
  if zRedirect <> nil then
  begin
    s := edInput.Text + sLineBreak;
    if rgCharset.ItemIndex = 1 then
      SetCodePage(s, GetOEMCP, True);
    zRedirect.WriteData(s);
    edInput.Text := '';
  end;
end;

procedure TRedirectThread.WriteData(Data: RawByteString); // переопределил!
var
  Written: Cardinal;
begin
  if hWriteIn <> 0 then
    WriteFile(hWriteIn, Data[1], Length(Data) * StringElementSize(Data), Written, nil);
end;


строка
Код:
SetCodePage(s, GetOEMCP, True);
выдает ошибку
Код:
[DCC Error] Unit1.pas(199): E2033 Types of actual and formal var parameters must be identical

при описании
Код:
var
  s: RawByteStr;
запускается - но результат тот же, ( команда проходит неправильно), мб ошибка где то в отправке а не в кодировке?
Ответить с цитированием
  #9  
Старый 08.10.2014, 17:47
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от OSIRIS
запускается - но результат тот же, ( команда проходит неправильно)
Это очень странно.

Хорошо, попробуем вариант с метатипом, который уже предлагал:
Код:
type
  OEMString = type AnsiString(CP_OEMCP);

procedure TForm1.btnWriteClick(Sender: TObject);
var
  s: RawByteString;
begin
  if zRedirect <> nil then
  begin
    zRedirect.WriteData(edInput.Text + sLineBreak);
    edInput.Text := '';
  end;
end;

procedure TRedirectThread.WriteData(const Data: OEMString); // <-- вот тут
var
  Written: Cardinal;
begin
  if hWriteIn <> 0 then
    WriteFile(hWriteIn, Data[1], Length(Data) * StringElementSize(Data), Written, nil);
end;
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
Этот пользователь сказал Спасибо Freeman за это полезное сообщение:
OSIRIS (09.10.2014)
  #10  
Старый 09.10.2014, 11:11
OSIRIS OSIRIS вне форума
Прохожий
 
Регистрация: 04.01.2008
Сообщения: 11
Репутация: 10
По умолчанию

заработало, спасибо ))
а можно поподробнее про ansistring? если честно не знал что у него могут быть параметры.... получается параметром указывается в какой кодировке будет строка?
Ответить с цитированием
  #11  
Старый 09.10.2014, 18:00
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от OSIRIS
а можно поподробнее про ansistring? если честно не знал что у него могут быть параметры.... получается параметром указывается в какой кодировке будет строка?
Для начала нужно уяснить, что тип UnicodeString -- метастрока, то есть общая структура, позволяющая хранить текстовые данные с разным физическим представлением символов. Кодировки на основе кодовых страниц и UTF-8 хранят символы в виде одного или нескольких байт, а UTF-16 -- в виде одного или двух слов, которые называют WideChar. Если не путаю, UnicodeString поддерживает также и UTF-32, в которой символы представлены двойными словами -- UCS4Char.

Особенность в том, что словные и двухсловные символы имеют лишь одно логическое представление -- UTF-16 и UTF-32 соответственно, а вот байтовые интерпретируются по-разному в зависимости от кодовой страницы. В Delphi это и реализовано: AnsiString является подтипом UnicodeString для байтовых символов, и ему можно задать кодовую страницу.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
Этот пользователь сказал Спасибо Freeman за это полезное сообщение:
OSIRIS (09.10.2014)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:12.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter