Anty-zamrażanie oraz szybka zmiana widoczności

0

Od razu mówię: wiem że C++ Builder to stare środowisko, ale w tym zacząłem program i w tym muszę skończyć. Mam 2 problemy:

Aplikacja pobiera oraz wypakowywuje (za pomocą ZipForge albo za pomocą oprogramowania zewnętrznego - problemy z curl) pewien plik. Ale podczas tej czynności zawsze pokazuje się te irytujące windowsowe kółeczko zamiast kursora i po chwili pisze że nie odpowiada, chociaż tak na prawdę właśnie pobiera i wypakowuje. Próbowałem dodać AntiFreeze, wtedy podczas pobierania jest OK, ale kiedy przychodzi to wypakowywania - znowu się zamraża. Kod:

					ProgressBar->Max=FTPc->Size("plik.zip");
					ProgressBar->Visible=true;
					Trwa->Visible=true;
					FTPc->Get("plik.zip", (zmienna + "\\scieka\\plik.zip").c_str());
					ProgressBar->Visible=false;
					Trwa->Visible=false;
					ProgressBar2->Visible=true;
					Trwa2->Visible=true;
					Archiver->FileName = (zmienna+ "\\sciezka\\plik.zip").c_str();
					Archiver->OpenArchive(fmOpenRead);
					Archiver->BaseDir = (zmienna + "\\sciezka").c_str();
					Archiver->ExtractFiles("*.*");
					Archiver->CloseArchive();
					ProgressBar2->Visible=false;
//koniec sposobu z ZipForge
					STARTUPINFO info2={sizeof(info2)};
					if (CreateProcess(zipath, zipcommand, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &info2, &processInfo2))
				{
					WaitForSingleObject(processInfo2.hProcess, INFINITE);
					CloseHandle(processInfo2.hProcess);
					CloseHandle(processInfo2.hThread);
				}
					remove((appdata + "\\sciezka\\plik.zip").c_str());
					Trwa2->Visible=false;
					ProgressBar2->Visible=false;
//koniec z zewnetrznym oprogramowaniem

Ktoś zna jakiś sposób na to? Coś może źle zrobiłem?
2. Chcę aby po najechaniu na obraz widoczność innego obrazu się zmieniała. Niestety po najechaniu na chwilę pokazuje się biały kwadrat i znika. Już kiedyś miałem z tym problem, i to rozwiązałem, ale teraz nie mogę znaleźć żadnego sposobu na to.

void __fastcall TMainForm::Timer1Timer(TObject *Sender)
{
pozycja_kursora();
if(x>MainForm->obraz1->Left+MainForm->Left && x<MainForm->obraz1->Left+162+MainForm->Left  &&
y>MainForm->obraz1->Top+MainForm->Top && y<MainForm->obraz1->Top+62+MainForm->Top)
{
	if(PLplay1->Visible==true){
	  MainForm->obraz2->Visible=true;
	  }
}
else
{
	  MainForm->obraz2->Visible=false;
	  }
}```
0

Po prostu wywołujesz długo trwającą operację w wątku głównym aplikacji i nie przetwarzasz komunikatów które docierają do okna. Wtedy Windows myśli, że aplikacja się zawiesiła i kursor zamienia się w kółeczko oraz wyszarzane jest okno.

Aby temu zapobiec możesz uruchamiać proces w pobocznym wątku (trudniejsze) albo (łatwiejsze) od czasu do czasu podczas wykonywania długiej operacji dać możliwość na przetworzenie komunikatów za pomocą:

Application->ProcessMessages();

Teraz pytanie gdzie to umieścić. Nie znam komponentu ZipForge, ale po pobieżnym przejrzeniu dokumentacji ma on ciekawe zdarzenie:
http://www.componentace.com/help/zf_guide/onoverallprogress.htm

Możesz je oprogramować. Będziesz miał wtedy postęp wypakowywania całości. W zdarzeniu po zaktualizowaniu progress bara dajesz wyżej wymieniony przeze mnie fragment i Windows już nie będzie tak reagował na długo trwające operacje.

0

@wojciennie mała uwaga, nie pisz takich odpowiedzi jako komentarze. Od tego są posty.

Co do drugiego problemu to moim zdaniem takie podejście jest mało eleganckie. O wiele lepiej będzie użyć zdarzenia OnMouseEnter oraz OnMouseLeave Bo domyślam się, że obrazki wyświetlasz w komponencie TImage

0

if(x>MainForm->obraz1->Left+MainForm->Left && x<MainForm->obraz1->Left+162+MainForm->Left &&
y>MainForm->obraz1->Top+MainForm->Top && y<MainForm->obraz1->Top+62+MainForm->Top)


[ScreenToClient](http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Controls_TControl_ScreenToClient.html)
[PtInRect](http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Types_PtInRect.html)
0

OK, rzeczywiście, nie zauważyłem nigdy OnMouseEnter oraz OnMouseLeave. Ale nadal na chwilę pokazuje się biały kwadrat w miejscu obrazka... Wie ktoś co z tym zrobić?

0

Problem już rozwiązany. Należy ustawić DoubleBuffered na true.
Jak ktoś chce poczytać to tutaj jest o tym, przydatny artykuł nawet.

0

@wojciennie nie zdążyłem odpisać :) Ale faktycznie DoubleBuffered pozwala na eliminację migotania formatki. Nawet podczas rysowania, czy jak coś robimy w zdarzeniu FormResize formatki. Wtedy nawet przy szybkich zmianach rozmiaru nie mamy migotania.

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