Przenoszenie focusa z AcroPDF na Edit1

0

Witam.

Pisze programik który ma za zadanie wyświetlić plik pdf.
Lista plików znajduje się w StringGridzie.
Natomiast wybór pliku następuje poprzez wpisanie jego numeru w Edit.
Po wybraniu i wyświetleniu pliku pole edit powinno być wciąż aktywne.

nazwa_pliku:=StringGrid1.Cells[1,StrToInt(Form1.Edit1.Text)]+'.pdf';
AcroPDF1.LoadFile(nazwa_pliku);
AcroPDF1.setShowToolbar(false);
AcroPDF1.setView('fit');
Edit1.SetFocus;

Plik się wczytuje i wyświetla lecz focus nie jest przenoszony z powrotem do Edit1.
Dlaczego ?

AcroPDF to ActiveX Adobe Reader.

Z góry dziękuję za pomoc.

0

spróbuj

Application.ProcessMessages
0

@TLesiu - ProcessMessages nie przynosi rezultatu, focus pozostaje na AcroPDF

0

nigdy nie korzystałem z AcroPDF, powiedz mi czy to jest komponent na formie głównej? czy wyświetla się jako nowe okno, czy odpala nowy program?

0

A może na próbę w wątku ustawiać Focus dopóki Edit1.Focused czy tam GetFocus = Edit1.Handle. A jeśli nadal jest problem to albo robić te ustawiamie Focusa jakos kod w procedurze przekazanej do Synchronize (jeśli użyłeś TThread) albo jako własny komunikat wysłany do formatki i po jego odbiorze wywolać focus, w przypadku jeśli robisz to pod WinAPI.

0

@TLesiu komponent wyświetla się na formie głównej.

@olesio nie używałem TThread ani WinAPI

0

To spróbuj zrobić tak jak radzę, bo ja nie mam teraz możliwości tego sprawdzić, jak reaguje kontrolka na focusowanie w wątku.

0

@olesio szczerze mówiąc nie do końca rozumiem jak to zrobić ale zaraz poczytam/poszukam i metodą prób i błędów spróbuje to zastosować.

0

Wystarczy wpisać w google Delphi wątki i masz mnóstwo informacji dla VCL. A pod WinAPI wystarczy pogooglować za przykładami użycia funkcji CreateThread.

0
olesio napisał(a):

A może na próbę w wątku ustawiać Focus dopóki Edit1.Focused czy tam GetFocus = Edit1.Handle. A jeśli nadal jest problem to albo robić te ustawiamie Focusa jakos kod w procedurze przekazanej do Synchronize (jeśli użyłeś TThread)

Możesz mi to jakoś łopatologicznej wyjaśnić?
Czytałem o wątkach, porobiłem jakieś przykładowe testy, chyba wiem o co ogólnie chodzi, ale tego o czym napisałeś nie rozumiem w ogóle :/...

0

No to do kursów marsz i się dokształcać. Napisałem Tobie najprościej jak się da. Stwórz na próbę wątek pod VCL (klasa TThread), przykładów w sieci masz mnóstwo. Spóbuj w tym wątku w pętli repeat ... until ustawiać ten Focus do skutku, aż Edit go uzyska. Po to wątek żeby program się nie blokował. A być może jakieś pojawianie się tej kontrolki do PDFów powoduje problemy z Focusem, że Edit nie może go złapać. Jeżeli się to nie powiedzie normalnie, to spróbuj to zrobić w procedurze z Synchronize w tym wątku. Poza tym no prosze Cie, bierzesz się za kontrolki ActiveX, a nie ogarniasz wątków? To coś jest nie tak :/

EDIT: uparłeś się, że nie chce Ci się zrobić tego z Synchronize (bo jednak pobieranie stanu focusa i jego ustawianie w wątku pobocznym powoduje problemy) pod VCL, to masz poniżej najprościej jak się dało pod WinAPI. Zawsze możesz też próbować zmieniać własność formatki ActiveControl na swój Edit1. Skoro ta kontrolka do PDFów powoduje kłopot z normalnym ustawieniem Focus'a dla innej kontrolki.

//...
const
  WM_TAKIEPODSTAWY = WM_USER + 2014;

var
  POldMainFormProc : Pointer;

function MainFormWindowProc(AHWnd : HWND; Msg : UINT; WParam : WParam; LParam : LParam) : LRESULT; stdcall;
begin
  case Msg of
    WM_TAKIEPODSTAWY :
      begin
        with Form1 do
        begin
          repeat
            Edit1.SetFocus;
          until Edit1.Focused;
        end;
      end;
  end;
  Result := CallWindowProc(POldMainFormProc, AHWnd, Msg, WParam, LParam);
end;

procedure GooglowanieOrazSamodzielnoscPlusUzywanieTBrainNieBoli(Param : Pointer); stdcall;
begin
  with Form1 do
  begin
    SendMessage(Form1.Handle, WM_TAKIEPODSTAWY, 0, 0);
  end;
end;

procedure TForm1.FormCreate(Sender : TObject);
begin
  POldMainFormProc := Pointer(SetWindowLong(Self.Handle, GWL_WNDPROC, Integer(@MainFormWindowProc)));
end;

procedure TForm1.Button1Click(Sender : TObject);
var
  ThreadId : Cardinal;
begin
  CreateThread(nil, 0, @GooglowanieOrazSamodzielnoscPlusUzywanieTBrainNieBoli, nil, 0, ThreadId);
end;
0

Pierwsza myśl po przeczytaniu Twojego poprzedniego postu to właśnie użycie repeat .. until w oddzielnym wątku, ale nie byłem pewny czy o to Ci chodzi - w każdym razie nie zdało egzaminu.Opcja z pętlą w Synchronize również...
Spróbowałem też wkleić Twój kod jednak focus nadal zostaje na AcroPDF.

A co do mojego stosowania ActiveX.
Szukałem po prostu sposobu na wyświetlenie pdf'a na formie i trafiłem właśnie na to w sieci.\

EDIT:
Bezskuteczne zmieniałem również własność Form1: ActiveControl na Edit1.

EDIT2:
Udało mi się osiągnąć zamierzony skutek dodając AcroPDF.Enabled:=false.

nazwa_pliku:=StringGrid1.Cells[1,StrToInt(Form1.Edit1.Text)]+'.pdf';
AcroPDF1.LoadFile(nazwa_pliku);
AcroPDF1.setShowToolbar(false);
AcroPDF1.setView('fit');
AcroPDF.Enabled:=false;
Edit1.SetFocus; 
0

To z tego można wnioskować, że ta kontrolka cały czas "kradnie" focus ustawiając go na siebie. Kontrolki które są Disabled nie mogą uzyskać Focusa. Jednak robiąć takową kontrolkę do tego PDF'a pozbawiasz się do niej jak rozumiem dostępu. Jednak jeżeli i tak to działa jak należy według Ciebie to ok, może tak ma być.

0

@olesio no właśnie mimo że AcroPDF.Enabled=false to procedury które są mi potrzebne (tj. gotoNextPage i gotoPreviousPage) działają poprawnie, więc w tym przypadku to "obejście" wystarczy.

Dziękuję serdecznie za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1