Wątki i URLDownlodToFile

0

Ja dalej męczę swój pierwszy większy program w WinAPI no i kolejne problemy...

#include <windows.h>
#include<windowsx.h>
#include <string>
#include <commctrl.h>
#include <shlwapi.h> 
#include<shlobj.h>
#include<atlstr.h>



 
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")

#define _CRT_SECURE_NO_DEPRECATE 1

#define _CRT_NONSTDC_NO_DEPRECATE 1



typedef HRESULT (*P_URLDownloadToFile)(      
   LPUNKNOWN pCaller,
   LPCTSTR szURL,
   LPCTSTR szFileName,
   DWORD dwReserved,
   void*
); 


using namespace std;


//tu sa deklaracje zmiennych...


class CBind: public IBindStatusCallback
{
public:
	virtual HRESULT STDMETHODCALLTYPE QueryInterface(const IID &riid,void **ppvObject)
	{
		return S_OK;
	}
	virtual ULONG STDMETHODCALLTYPE AddRef( void)
		{
		return S_OK;
	}
    virtual ULONG STDMETHODCALLTYPE Release( void)
		{
		return S_OK;
	}
	 virtual HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD dwReserved, IBinding *pib)
		 {
		return S_OK;
	}
        
        virtual HRESULT STDMETHODCALLTYPE GetPriority(LONG *pnPriority)
			{
		return S_OK;
	}
        
        virtual HRESULT STDMETHODCALLTYPE OnLowResource(DWORD reserved)
			{
		return S_OK;
	}
        
        virtual HRESULT STDMETHODCALLTYPE OnProgress(ULONG ulProgress,ULONG ulProgressMax,ULONG ulStatusCode,LPCWSTR szStatusText)
			{
			switch(ulStatusCode)
		{
		case BINDSTATUS_DOWNLOADINGDATA:
			
			ULONG progres;
			progres=(100 * ulProgress / ulProgressMax)+1;
		 SendMessage(progressbar,PBM_SETPOS,100 * ulProgress / ulProgressMax, 0);
			char liczba[5];
           sprintf(liczba,"%u",progres);
		   SetWindowText(label3,liczba);  //pokazywanie postepu w static'u
			
		
			break;

		case BINDSTATUS_ENDDOWNLOADDATA:
       //jesli koniec to zakoncz watek i wyzeruj progressbar
			  TerminateThread(hThread,0);
			  SendMessage(progressbar,PBM_SETPOS,(WPARAM)0, 0);
			
			  sciaganie=false;
			break;
		}
		return S_OK;
		
	}
        
        virtual HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT hresult,LPCWSTR szError)
			{
		return S_OK;
	}
        
        virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD *grfBINDF,BINDINFO *pbindinfo)
			{
		return S_OK;
	}
        
        virtual HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD grfBSCF,DWORD dwSize,FORMATETC *pformatetc,STGMEDIUM *pstgmed)
			{
		return S_OK;
	}
        
        virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(REFIID riid,IUnknown *punk)
			{
		return S_OK;
	}

};
CBind *bnd=new CBind;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	
	//WYPEŁNIANIE STRUKTURY i tworzenie okna i przyciskow
 
 ShowWindow(hwnd, nCmdShow); //Pokaż okienko...
 UpdateWindow(hwnd);
 //Pętla komunikatów
 while(GetMessage(&Komunikat, NULL, 0, 0))
 {
  TranslateMessage(&Komunikat);
  DispatchMessage(&Komunikat);
 }
 return Komunikat.wParam;
}



//OBSŁUGA ZDARZEŃ
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	

 switch(msg)
 {
 case WM_CREATE:
	     progressbar=CreateWindowEx(0,PROGRESS_CLASS,0,WS_VISIBLE|WS_CHILD|PBS_SMOOTH,150,280,368,42,hwnd,0,hInstance,0);
	 statusbar = CreateWindowEx(0,STATUSCLASSNAME,(LPCTSTR) NULL,WS_VISIBLE|WS_CHILD,0, 0, 0, 0,hwnd,NULL,hInstance,NULL);
		 
	 break;
  case WM_CLOSE:
     DestroyWindow(hwnd);
  break;
  case WM_COMMAND:
	  switch(wParam)
	  {
	  case gsciagaj: // jesli nacisnieto guzik sciagania
		
			  if(sciaganie==false)
		 {
		  sciaganie=true;
		  SetWindowText(sciagaj,"Anuluj"); //zmiana tekstu na guziku
				 
		  hThread = CreateThread(NULL, 0, Thread, NULL, 0, &ThreadId); //tworzenie watku ktory sciaga
		  }
		  else
		  {
			  sciaganie=false;
			 SetWindowText(sciagaj,"Ściągaj");
			   TerminateThread(hThread,0);      //tu powinno konczyc watek i ustawiac progresbar na 0 i kasowac plik
			  SendMessage(progressbar,PBM_SETPOS,(WPARAM)0,0);		
	                  DeleteFile(tu sciezka do pliku ktory sciagam);
		  }
		
		 
		  break;
	 	  }
	  

	  break;
  case WM_DESTROY:
	  FreeLibrary(hLib);
   PostQuitMessage(0);
  break;
  default:
   return DefWindowProc(hwnd, msg, wParam, lParam);
  }
 return 0;
}

DWORD WINAPI Thread(PVOID pVoid)
{
	
 _URLDownloadToFile(NULL,link.c_str(),sciezka.c_str(),0,bnd);
 return 1;
}

Problem polega na tym, że cokolwiek robię w ENDDOWNLOADDATA nie przynosi skutku, nie wiem czy wątek się kończy, ale progresbar sie nie zeruje, to samo jak wcisnę anulowanie ściągania. Plik się nie usuwa i progresbar sie nie zeruje.
Kod jest powycinany więc na to nie patrzcie...

0

Przed wyzerowaniem ubiłeś wątek, który to miał zrobić więc nie dziw się, że się nic nie dzieje. Nie ubijaj wątku przez TerminateThread, pozwól mu się normalnie zakończyć, czyli nie rób z nim nic. Po zakończeniu ściągania funkcja URLDownloadToFile skończy działanie, czyli funkcja Thread również kończąc tym samym wątek. TerminateThread nie służy do zakończenia wątku tylko do jego przerwania w wyjątkowych sytuacjach.

I zmień temat bo obecny nijak się ma do problemu.

0

Chyba nie mogę zmienić tematu, bo nie jestem zarejestrowany...

Ok, dzięki za info o tym kończeniu wątku, nie wiedziałem że sam się zakończy po skończeniu ściągania.
Problem jednak jest nadal:

case BINDSTATUS_ENDDOWNLOADDATA:
                           SendMessage(progressbar,PBM_SETPOS,(WPARAM)0, 0); //ok juz sie zeruje              
                           sciaganie=false; // to sie nie przestawia na false
                           zmienna+=1; //tu wywala
                        break;

Jak debuguję program, to widzę, że ściąganie mi się nie przestawia tu na false, w dodatku co najdziwniejsze jak zadeklaruje globalnie zmienną "zmienna" i ją tak zwiększam jak wyżej, to wywala mi błąd debuggera i proponuje poszukać:

How to debug Buffer Overrun Issues.

Szukałem o tym i czytałem, ale nic nie znalazłem co mogłoby rozwiązać problem.

No i kwestia usuwania pliku. Podczas ściągania chcę żeby przerwało i usunęło ten fragment, więc robię TerminateThread i DeleteFile ale plik pozostaje. Jest otwarty czy co? Nie sypie żadnymi errorami...

0

bo nie jestem zarejestrowany...
Najwyższa pora to zmienić :)

Wklej cały kod tutaj->http://pastebin.4ptogrammers.net i daj linka.

_URLDownloadToFile
Dalej ładujesz dynamicznie ? Nie potrzebnie. W innym wątku już pisałem - dodaj urlmon.lib do projektu. Opcje projektu->linker->input lub coś podobnego albo w kodzie:

#pragma comment(lib, "urlmon")

i używaj normalnie URLDownloadToFile z "urlmon.h".

No i kwestia usuwania pliku. Podczas ściągania chcę żeby przerwało i usunęło ten fragment, więc robię TerminateThread i DeleteFile ale plik pozostaje. Jest otwarty czy co? Nie sypie żadnymi errorami...
Jeśli chcesz przerwać ściąganie zwróć E_ABORT w OnProgress.
NIE UŻYWAJ TerminateThread nigdy. Jak ubijasz wątek to wszystkie uchwyty które pootwierał zostają otwarte, zarezerwowana dynamicznie pamięć nie jest zwalniana ... dlatego nie dało się usunąć tego pliku.

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