Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Проблема с с выводом... (http://forum.oszone.net/showthread.php?t=159003)

ultrakiller 03-12-2009 09:17 1285648

Проблема с с выводом...
 
Есть вот такой код, он рабочий..
Код:

procedure TForm1.RunDosInMemo(CmdLine:String;AMemo:TMemo);
const
  ReadBuffer = 2400;
var
  Security        : TSecurityAttributes;
  ReadPipe,WritePipe  : THandle;
  start          : TStartUpInfo;
  ProcessInfo    : TProcessInformation;
  Buffer          : PChar;
  BytesRead      : DWord;
  Apprunning      : DWord;
  WasOK          : Boolean;
begin
  Screen.Cursor:=CrHourGlass;

  With Security do
  begin
    nlength              := SizeOf(TSecurityAttributes);
    binherithandle      := true;
    lpsecuritydescriptor := nil;
  end;

  if Createpipe (ReadPipe, WritePipe, @Security, 0) then
    begin
      Buffer  := AllocMem(ReadBuffer + 1);
      FillChar(Start,Sizeof(Start),#0);

      start.cb          := SizeOf(start);
      start.hStdOutput  := WritePipe;
      start.hStdInput  := ReadPipe;
      start.dwFlags    := STARTF_USESTDHANDLES +
                          STARTF_USESHOWWINDOW;
      start.wShowWindow := SW_HIDE;
      if CreateProcess(nil,
          PWChar(WideString(CmdLine)),
          nil,//@Security,
          nil,//@Security,
          true,
          NORMAL_PRIORITY_CLASS,
          nil,
          nil,
          start,
          ProcessInfo)
        // CreateProcess(nil, 'CmdLine', nil, nil, true, NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo)
      then
      begin
        CloseHandle(WritePipe);
        Apprunning := WaitForSingleObject (ProcessInfo.hProcess,100);

        try
          repeat
            WasOK:=ReadFile(ReadPipe,Buffer[0], ReadBuffer,BytesRead,nil);
            Buffer[BytesRead]:= #0;
            OemToAnsi(PAnsiChar(Buffer),PAnsiChar(Buffer));
            AMemo.Text := AMemo.text + String(Buffer);

            Application.ProcessMessages;
          until (not WasOK) or ( BytesRead = 0 );
        finally
          CloseHandle(ProcessInfo.hProcess);
          CloseHandle(ProcessInfo.hThread);
        end;
    end;

    FreeMem(Buffer);
    CloseHandle(ReadPipe);
  end;
  Screen.Cursor:=CrDefault;

end;


procedure TForm1.Button1Click(Sender: TObject);
begin
 Memo1.Clear;
 RunDosInMemo('ping 10.1.0.115',Memo1);
end;

Проблема что при выводе в Memo он выдает квадратики...
Что вы посоветуете
Код взял с форума , и доработал с помощью статьи
статьи
Среда Delphi 2009

Admiral 04-12-2009 01:20 1286316

ultrakiller, посоветую сделать перекодировку, функцией MultiByteToWideChar() ответа с консоли, перед отправкой в Memo.
Пример для Делфи не приведу, есть на С
Код:

BOOL ret = true;
char BufferA[MAX_PATH]="";

DWORD NumberOfBytesRead = 0;

do
{
        ret = ReadFile(hReadPipe, &BufferA, MAX_PATH-1, &NumberOfBytesRead, 0);
        if (NumberOfBytesRead < MAX_PATH-1)
                BufferA[NumberOfBytesRead]='\0';
        else
                BufferA[MAX_PATH-1]='\0';

        wchar_t BufferW[MAX_PATH]=L"";
        MultiByteToWideChar(CP_OEMCP, 0, BufferA, -1, BufferW, MAX_PATH);
        if (hEdit != NULL)
                AddTextW(hEdit, BufferW);
        //...
}while (ret != 0);

Это фрагмент кода с программы MultiBoot
Фрагмент добавлен в программу после перевода с VB6 - Capture the Output of a DOS application, в которой не было перекодировки.

ultrakiller 04-12-2009 09:22 1286450

Спасибо за ответ, но подскажите все-таки в чем глюк

Admiral 05-12-2009 20:25 1287604

ultrakiller, последний раз работал с Делфи в 7й Версии.
Выскажу предположение, что Memo в Делфи 2009, склонна к Юникоду, так что вызывая MultiByteToWideChar() с первым параметром CP_OEMCP идёт перекодировка с консольной кодировки непосредственно в Юникод, а не просто смена кодировки, как в случаи с OemToAnsi
Например в VB.NET текст для подобного компоненте желательно должен быть в Юникод кодировке, а для Win32 Api элемента управления EDIT, это не принципиально (видимо для обратной совместимости).

Drongo 05-12-2009 21:53 1287652

Цитата:

Цитата Admiral
что Memo в Делфи 2009, склонна к Юникоду »

Я уверен что там Unicode, т.к. C++ Builder 2009 поставляется на одном диске с Delphi 2009, а в первом Memo на юникоде.

Я не знаю только, есть ли в Delphi 2009 функции аналогичные в C++

Цитата:

Цитата Drongo
Как мне сказали, нужно указывать вторым параметром в SaveToFile указывать соответствующую кодировку:
Код:
TEncoding::Unicode
TEncoding::UTF8
TEncoding::Default
TEncoding::ASCII »

Возможно, не пропобовал, для открытия нужно воспользоваться (C++) аналогичными для Delphi, функциями чтения
Цитата:

static TEncoding* __fastcall GetASCII();
static TEncoding* __fastcall GetBigEndianUnicode();
static TEncoding* __fastcall GetDefault();
static TEncoding* __fastcall GetUnicode();
static TEncoding* __fastcall GetUTF7();
static TEncoding* __fastcall GetUTF8();

opel431 05-09-2011 08:57 1746352

Цитата:

Цитата ultrakiller
Проблема что при выводе в Memo он выдает квадратики...
Что вы посоветуете »

Цитата:

Цитата ultrakiller
Среда Delphi 2009 »

var
Buffer:PAnsiChar;
......
......

begin
.....
OemToChar(Buffer,PWideChar(Buffer)); //XP
; OemToAnsi(Buffer, Buffer) //Seven
AMemo.Text:=AMemo.Text+String(Buffer);
.....
end;


Время: 06:10.

Время: 06:10.
© OSzone.net 2001-