Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.04.2011, 06:26   #1
-=blAck=-
 
Аватар для -=blAck=-
 
Регистрация: 25.08.2010
Сообщений: 9
По умолчанию Проблемка с получением текста статусбара Java-приложения

Хотелось бы выдирать текст из пары элементов управления в стороннем Java-приложении. Хотя бы из статусбара.
По Handle находится только окно класса SunAwtFrame, которое не имеет дочерних Handle, Через Spy++ проверил - статусбар и правда своего хЭндла не имеет.
http://www.codeguru.com/forum/showpo...42&postcount=4 - тут нашел мысль интересную, но вот с реализацией как-то тяжко...
По идее надо получить адрес метода по имени метода и хЭндлу окна и вызвать его. Вот как этот самый адрес метода получить - может кто-нибудь подсказать?
Заранее спасибо!
Иначе, похоже, придется прикручивать что-то типа cap.exe для распознавания текста с картинки, но это ж жуткий изврат...

Последний раз редактировалось mihali4; 03.11.2011 в 01:23.
-=blAck=- вне форума Ответить с цитированием
Старый 04.04.2011, 15:12   #2
-=blAck=-
 
Аватар для -=blAck=-
 
Регистрация: 25.08.2010
Сообщений: 9
По умолчанию

Таки пришлось прикрутить консольную распознавалку GOCR...
В принципе также можно и Tesseract OCR присобачить но он ощутимо больше и больше вероятность что-то потерять.
Вдруг кому-то будет полезно, выкладываю исходник - скринит указанную область экрана и скармливает в распознавалку. Вывод читает из консольного StdOut:

Код:
type TClr=Record
       case Integer of
       0: (Red,Green,Blue,A:Byte);
       1: (Color:TColor);
     end;

//...

function RunConsoleApp(AppName,RunParams:string):String;
const ReadBuffSz=10240; //10 kB Buffer
var Security:TSecurityAttributes;
    StdOutPipeR,StdOutPipeW:THandle;
    StUpInfo:TStartUpInfo;
    ProcessInfo:TProcessInformation;
    Buff:PAnsiChar;
    BytesRead:DWORD;
    n:Integer;
    AppParams,AppDir:String;
begin
  with Security do
  begin
    nLength              :=SizeOf(TSecurityAttributes);
    lpSecurityDescriptor :=nil;
    bInheritHandle       :=True;
  end;
  FillChar(ProcessInfo,Sizeof(TProcessInformation),#0);
  Buff:=nil;
  Result:='';
  AppParams:=ExtractFileName(AppName)+' '+RunParams;
  AppDir:=ExtractFilePath(AppName);

  if CreatePipe(StdOutPipeR,StdOutPipeW,@Security,0) then
  try
    try
      Buff:=AllocMem(ReadBuffSz);
      FillChar(StUpInfo,Sizeof(TStartUpInfo),#0);

      with StUpInfo do
      begin
        cb:=SizeOf(TStartUpInfo);
        hStdOutput:=StdOutPipeW;
        dwFlags:=STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
        wShowWindow := SW_HIDE;
      end;

      if CreateProcess(PChar(AppName),PChar(AppParams),
          nil,                                        // Process sequrity attributes
          nil,                                        // Thread sequrity attributes
          True,                                       // Inherit handles
          CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,  // Creation flags
          nil,                                        // Environment block
          PChar(AppDir),StUpInfo,ProcessInfo) then
      try
        n:=0;
        while (n<10) and (WaitForSingleObject(ProcessInfo.hProcess,300)=WAIT_TIMEOUT) do
        begin
          Inc(n);
          Application.ProcessMessages;
        end;
        ReadFile(StdOutPipeR,Buff[0],ReadBuffSz-1,BytesRead,nil);
        Result:=String(PAnsiChar(Buff));
      finally //CreateProcess
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
      end; //CreateProcess
    finally //AllocMem(ReadBuffSz)
      FreeMem(Buff);
    end; //AllocMem(ReadBuffSz)
  finally //CreatePipe(StdOutPipeR,StdOutPipeW
    CloseHandle(StdOutPipeR);
    CloseHandle(StdOutPipeW);
  end; //CreatePipe(StdOutPipeR,StdOutPipeW
end;

Последний раз редактировалось -=blAck=-; 04.04.2011 в 15:17.
-=blAck=- вне форума Ответить с цитированием
Старый 04.04.2011, 15:13   #3
-=blAck=-
 
Аватар для -=blAck=-
 
Регистрация: 25.08.2010
Сообщений: 9
По умолчанию

Всё не влезло, вот продолжение:
Код:
function ScreenShotRectOCR(x1,y1,x2,y2,BWBorder:Integer;OCRParams,Filename:String):String;
var w,h,xx1,yy1,x,y,i:Integer;
    Img:TPngImage;
    dc:HDC;
    lpPal:PLOGPALETTE;
    Ptr:PByteArray;
    ImgBin: Array[1..2] of Array of Array of TClr;
    PBMData:TStringList;
    PBMRow:String;
begin
  dc:=GetDc(0); //get the screen dc
  if (dc=0) then Exit;
  Img:=nil;
  PBMData:=nil;
  Result:='';

  w:=Abs(x2-x1)+1;
  h:=Abs(y2-y1)+1;

  if x1<x2
  then xx1:=x1
  else xx1:=x2;
  if y1<y2
  then yy1:=y1
  else yy1:=y2;

  try
    try
      Img:=TPngImage.CreateBlank(COLOR_RGB,8,1,1);
      Img.SetSize(w,h);
      if ((GetDeviceCaps(dc,RASTERCAPS) and RC_PALETTE) = RC_PALETTE) then
      begin
        GetMem(lpPal,SizeOf(TLOGPALETTE)+(255*SizeOf(TPALETTEENTRY))); //allocate memory for a logical palette
        FillChar(lpPal^,SizeOf(TLOGPALETTE)+(255*SizeOf(TPALETTEENTRY)),#0); //zero it out to be neat
        lpPal^.palVersion:=$300; //fill in the palette version
        lpPal^.palNumEntries:=GetSystemPaletteEntries(dc,0,256,lpPal^.palPalEntry); //grab the system palette entries
        if (lpPal^.PalNumEntries<>0) then Img.Palette:=CreatePalette(lpPal^); //create the palette
        FreeMem(lpPal,SizeOf(TLOGPALETTE)+(255*SizeOf(TPALETTEENTRY)));
      end;
      BitBlt(Img.Canvas.Handle,0,0,w,h,dc,xx1,yy1,SRCCOPY); //copy from the screen to the bitmap
    except
      FreeAndNil(Img);
    end;
  finally
    ReleaseDc(0,dc); //release the screen dc
  end;

  if Img=nil then Exit;

  try
    //Read image and resize it X2, add right zone
    SetLength(ImgBin[1],w*2+10,h*2);
    for y:=0 to h-1 do
    begin
      Ptr:=Img.ScanLine[y];
      for x:=0 to w-1 do
      begin
        ImgBin[1][x*2,y*2]:=RGBAClr(Ptr^[x*3+2],Ptr^[x*3+1],Ptr^[x*3],0);
        if (x>0) then ImgBin[1][x*2-1,y*2]:=AvgClr(ImgBin[1][x*2-2,y*2],ImgBin[1][x*2,y*2]);
        if (x>0) and (y>0) then ImgBin[1][x*2-1,y*2-1]:=AvgClr(ImgBin[1][x*2-2,y*2],ImgBin[1][x*2-2,y*2-2],ImgBin[1][x*2,y*2-2],ImgBin[1][x*2,y*2]);
        if (y>0) then ImgBin[1][x*2,y*2-1]:=AvgClr(ImgBin[1][x*2,y*2-2],ImgBin[1][x*2,y*2]);
      end;
      ImgBin[1][w*2-1,y*2]:=AvgClr(ImgBin[1][w*2-2,y*2],ImgBin[1][0,y*2]);
      for x:=w*2 to w*2+9 do ImgBin[1][x,y*2]:=ImgBin[1][0,y*2]; //Add grey zone at right
      if (y>0) then
      begin
        for x:=w*2 to w*2+9 do ImgBin[1][x,y*2-1]:=AvgClr(ImgBin[1][x,y*2-2],ImgBin[1][x,y*2]); //Add grey zone at right
        ImgBin[1][w*2-1,y*2-1]:=AvgClr(ImgBin[1][w*2-1,y*2-2],ImgBin[1][w*2-1,y*2]);
      end;
    end;
    for x:=0 to w*2+9 do ImgBin[1][x,h*2-1]:=ImgBin[1][x,h*2-2]; //Duplicate bottom line
    w:=w+5;

    //Save image as BW
    w:=w*2;
    h:=h*2;
    Img.SetSize(w,h);
    PBMData:=TStringList.Create;
    PBMData.Add('P1');
    PBMData.Add(IntToStr(w)+' '+IntToStr(h));
    for y:=0 to h-1 do
    begin
      Ptr:=Img.ScanLine[y];
      PBMRow:='';
      for x:=0 to w-1 do
      begin
        if Round(0.299*ImgBin[1][x,y].Red+0.587*ImgBin[1][x,y].Green+0.114*ImgBin[1][x,y].Blue)>BWBorder
        then PBMRow:=PBMRow+'0 '
        else PBMRow:=PBMRow+'1 ';
        Ptr^[x*3] := ImgBin[1][x,y].Blue;
        Ptr^[x*3+1]:=ImgBin[1][x,y].Green;
        Ptr^[x*3+2]:=ImgBin[1][x,y].Red;
      end;
      Delete(PBMRow,Length(PBMRow),1);
      PBMData.Add(PBMRow);
    end;
    Img.SaveToFile(Filename);
    if DirectoryExists(ExtractFilePath(Application.ExeName)+'OCR') or CreateDir(ExtractFilePath(Application.ExeName)+'OCR') then
    begin
      PBMData.SaveToFile(ExtractFilePath(Application.ExeName)+'OCR\img.pbm');
      if FileExists(ExtractFilePath(Application.ExeName)+'OCR\gocr.exe') then
      Result:=RunConsoleApp(ExtractFilePath(Application.ExeName)+'OCR\gocr.exe',OCRParams+' '+'img.pbm');
    end;
  finally
    Img.Free;
    PBMData.Free;
  end;
end;
-=blAck=- вне форума Ответить с цитированием
Старый 04.04.2011, 16:51   #4
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Ужас, а через MSAA разве не работало?
eduard93 вне форума Ответить с цитированием
Старый 05.04.2011, 10:52   #5
-=blAck=-
 
Аватар для -=blAck=-
 
Регистрация: 25.08.2010
Сообщений: 9
По умолчанию

Сейчас проверю... Но далеко не факт т.к. там жаба-приложение.
...
Проверил - нифига, только заголовки окон читает.
Этого я добивался и через WinAPI.
А вот компоненты внутри окон - хрен видит.

Последний раз редактировалось -=blAck=-; 05.04.2011 в 11:10.
-=blAck=- вне форума Ответить с цитированием
Старый 05.04.2011, 12:16   #6
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Я был о джавовском фреймворке более высокого мнения. По крайней мере с .Net-приложением этот способ должен работать.
eduard93 вне форума Ответить с цитированием
Старый 05.04.2011, 12:23   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Я был о джавовском фреймворке более высокого мнения.
а в честь чего он обязан кому попало данные отдавать?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.04.2011, 12:27   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Мммм... как насчёт "в честь улучшения экосистемы программ?".
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.

Последний раз редактировалось mihali4; 03.11.2011 в 01:24.
GunSmoker вне форума Ответить с цитированием
Старый 05.04.2011, 12:51   #9
eduard93
Форумчанин
 
Регистрация: 06.12.2010
Сообщений: 300
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
а в честь чего он обязан кому попало данные отдавать?
В честь людей с проблемМ(???)ами зрения, такие штуки в первую очередь им нужны.

Последний раз редактировалось mihali4; 03.11.2011 в 01:25.
eduard93 вне форума Ответить с цитированием
Старый 05.04.2011, 13:14   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
В честь людей с проблемами зрения, такие штуки в первую очередь им нужны.
Экранной лупы мало?
Тем более масштабирование это не отдача текста.
Во вторых, тогда автор программы должен под это рассчитывать.
А не фреймворк делать все за него.

Цитата:
Мммм... как насчёт "в честь улучшения экосистемы программ?"
программа имеет право быть изолированной системой.

Да кстати, насчет зрения, а зачем если плохое зрение ставить максимальное разрешение монитора?
Я на своем монике 1280/1024 ставлю 1024/768, потому что максимум мне не удобен(хоть зрение и отличное, но просто не уютно)
Так же и моя девушка делает на своем компе.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось mihali4; 03.11.2011 в 01:26.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с получением текста из label чужого окна, при том что, текст и класс уже известны. Человек_Борща Общие вопросы Delphi 1 15.01.2011 18:49
Java-приложения в телефоне. alina-alina Общие вопросы по Java, Java SE, Kotlin 7 03.03.2010 22:27
Проблема с получением текста в tclientsocket zver777 Работа с сетью в Delphi 1 24.09.2009 22:50
Проблемка с подсветкой текста blackstersl Общие вопросы Delphi 2 22.06.2009 10:37
Запуск Java Приложения Mega Общие вопросы по Java, Java SE, Kotlin 31 23.03.2009 09:30