jpg downloaden und anzeigen



  • Hallo,
    ich sitze an einem Programm, das mir eine Bilddatei aus dem Netzt liest und sie dann anzeigt. Das Problem ist, dass sich das Programm immer nach einigen Minuten aufhängt mit einem Fehler "Access violation".

    Hier der Code. Ich denke, dass der Fehler auftritt, wenn die Grafik irgendwie beschädigt geladen wurde, obwohl ich eigentlich alles getan habe, um das zu verhindern.

    Ich hoffe, dass ihr mir weiterhelfen könnt.

    Michael

    // daxomat LOGGERDlg.cpp : Implementierungsdatei
    //
    
    #include "stdafx.h"
    #include "daxomat LOGGER.h"
    #include "daxomat LOGGERDlg.h"
    #include <windows.h>
    #include <wininet.h>
    #include "afxctl.h"
    #include <afxpriv.h>
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CAboutDlg-Dialogfeld für Anwendungsbefehl "Info"
    
    class CAboutDlg : public CDialog
    {
    public:
    	CAboutDlg();
    // Dialogfelddaten
    	//{{AFX_DATA(CAboutDlg)
    	enum { IDD = IDD_ABOUTBOX };
    	//}}AFX_DATA
    
    	// Vom Klassenassistenten generierte Überladungen virtueller Funktionen
    	//{{AFX_VIRTUAL(CAboutDlg)
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV-Unterstützung
    	//}}AFX_VIRTUAL
    
    // Implementierung
    protected:
    	//{{AFX_MSG(CAboutDlg)
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    	//{{AFX_DATA_INIT(CAboutDlg)
    	//}}AFX_DATA_INIT
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CAboutDlg)
    	//}}AFX_DATA_MAP
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    	//{{AFX_MSG_MAP(CAboutDlg)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CDaxomatLOGGERDlg Dialogfeld
    
    CDaxomatLOGGERDlg::CDaxomatLOGGERDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CDaxomatLOGGERDlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CDaxomatLOGGERDlg)
    		// HINWEIS: Der Klassenassistent fügt hier Member-Initialisierung ein
    	//}}AFX_DATA_INIT
    	// Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CDaxomatLOGGERDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CDaxomatLOGGERDlg)
    	DDX_Control(pDX, IDC_Report, m_report);
    	//}}AFX_DATA_MAP
    }
    
    BEGIN_MESSAGE_MAP(CDaxomatLOGGERDlg, CDialog)
    	//{{AFX_MSG_MAP(CDaxomatLOGGERDlg)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_BN_CLICKED(IDC_run, Automatik_Modus)
    	ON_WM_TIMER()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CDaxomatLOGGERDlg Nachrichten-Handler
    
    BOOL CDaxomatLOGGERDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
    	// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{	
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden
    	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden
    
    	// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen	
    		// StatusBar erzeugen
    		m_StatusBar = new CStatusBarCtrl;
    		m_StatusBar->Create(WS_CHILD|WS_VISIBLE, CRect(0, 0, 0, 0), this, 0);
    
    		// StatusBar einteilen
    //		int nTeilung[3]= {240, 320, -1};
    //		m_StatusBar->SetParts(3, nTeilung);
    
    		int nTeilung[1]= {-1};
    		m_StatusBar->SetParts(1, nTeilung);
    
    		// Text in die einzelnen Spalten schreiben
    		m_StatusBar->SetText((""),0, 0);
    //		m_StatusBar->SetText((""), 1, 0);
    //		m_StatusBar->SetText((""), 2, 0);
    
    		// Bestimmung des aktuellen Programmpfads
    			// Kompletten Pfad der Anwendung ermitteln
    			CString strPfads;
    			strPfads = GetCommandLine();
    
    			// Dateierweiterung abschneiden
    			int nPos = strPfads.ReverseFind( '\\');
    			strPfads = strPfads.Mid(1, nPos-1);
    
    			strPfadl.Format("%s%s",strPfads,"\\data\\tmp.jpg");
    
    		/////////////////////////////////////////////////
    		// Konfiguration des Listenelements
    
    		m_report.InsertColumn(0, "Trade Nr." ,	LVCFMT_LEFT,	100);
    		m_report.InsertColumn(1, "Aktion" ,		LVCFMT_LEFT,	200);
    		m_report.InsertColumn(2, "Kurs" ,		LVCFMT_CENTER,	100);
    		m_report.InsertColumn(3, "Uhrzeit" ,	LVCFMT_CENTER,	100);
    		m_report.InsertColumn(4, "Datum" ,		LVCFMT_CENTER,	100);
    
    		// Bild laden
    		show_blank=true;
    		blank_img.LoadBitmap( IDB_blank );
    
    		test=0;
    		lock_download=false;
    
    	return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }
    
    void CDaxomatLOGGERDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    	{
    		CAboutDlg dlgAbout;
    		dlgAbout.DoModal();
    	}
    	else
    	{
    		CDialog::OnSysCommand(nID, lParam);
    	}
    }
    
    // Wollen Sie Ihrem Dialogfeld eine Schaltfläche "Minimieren" hinzufügen, benötigen Sie 
    //  den nachstehenden Code, um das Symbol zu zeichnen. Für MFC-Anwendungen, die das 
    //  Dokument/Ansicht-Modell verwenden, wird dies automatisch für Sie erledigt.
    
    void CDaxomatLOGGERDlg::OnPaint() 
    {
    	if(show_blank){
    
    	  CClientDC dc( this );
    	  BITMAP bm;
    	  blank_img.GetObject( sizeof( bm ), &bm );
    	  CDC SpeicherDC;
    	  SpeicherDC.CreateCompatibleDC( &dc );
    	  SpeicherDC.SelectObject( &blank_img );
    	  CRect Rect;
    	  GetClientRect( &Rect );
    	  dc.SetStretchBltMode( HALFTONE );
    
    	  dc.StretchBlt( 245, 130,
    					 117, 36, &SpeicherDC,
    					 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
    	}else{
    
    		// Größen- & Positionsvariablen
    		int		x=1,y=20;
    		int     nWidth  = GetSystemMetrics(SM_CXSCREEN);
    		int     nHeight = GetSystemMetrics(SM_CYSCREEN);
    
    		CRect	cR_chart, rc;
    		CRgn	rgn;
    
    		OLE_XSIZE_HIMETRIC width;	
    		OLE_YSIZE_HIMETRIC height;
    
    		//Main DC
    		CClientDC dc(this);
    		dc.SetBkMode(TRANSPARENT);
    
    		m_bild->get_Width(&width);
    		m_bild->get_Height(&height);
    		width-=200;
    
    		double faktor=	1; int size_x,size_y;
    		size_x=(int)(	(width*96/2540	)*faktor	);
    		size_y=(int)(	(height*96/2540	)*faktor	);
    
    		cR_chart.left		=x;
    		cR_chart.top		=y;
    		cR_chart.right		=x+size_x;
    		cR_chart.bottom		=y+size_y-6;
    
    		rgn.CreateRectRgnIndirect( &cR_chart );
    		dc.SelectClipRgn(&rgn);
    		rgn.DeleteObject();
    
    		GetClientRect(&rc);
    
    		m_bild->Render(dc, 
    						x, y, size_x, size_y, 
    						0, height, width, -height, &rc);
    
    		dc.RectVisible(CRect (0,0,200,200));
    	}
    
    	CDialog::OnPaint(); 
    }
    
    // Die Systemaufrufe fragen den Cursorform ab, die angezeigt werden soll, während der Benutzer
    //  das zum Symbol verkleinerte Fenster mit der Maus zieht.
    HCURSOR CDaxomatLOGGERDlg::OnQueryDragIcon()
    {
    	return (HCURSOR) m_hIcon;
    }
    
    BOOL CDaxomatLOGGERDlg::DelTempFiles()
    {
        BOOL bResult = FALSE;
        BOOL bDone = FALSE;
        LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL;
    
        DWORD  dwTrySize, dwEntrySize = 4096; // start buffer size
        HANDLE hCacheDir = NULL;
        DWORD  dwError = ERROR_INSUFFICIENT_BUFFER;
    
        do
        {
            switch (dwError)
            {
                // need a bigger buffer
                case ERROR_INSUFFICIENT_BUFFER:
                    delete [] lpCacheEntry;
                    lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize];
                    lpCacheEntry->dwStructSize = dwEntrySize;
                    dwTrySize = dwEntrySize;
                    BOOL bSuccess;
                    if (hCacheDir == NULL)
    
                        bSuccess = (hCacheDir
                          = FindFirstUrlCacheEntry(NULL, lpCacheEntry,
                          &dwTrySize)) != NULL;
                    else
                        bSuccess = FindNextUrlCacheEntry(hCacheDir, lpCacheEntry, &dwTrySize);
    
                    if (bSuccess)
                        dwError = ERROR_SUCCESS;
                    else
                    {
                        dwError = GetLastError();
                        dwEntrySize = dwTrySize; // use new size returned
                    }
                    break;
    
                 // we are done
                case ERROR_NO_MORE_ITEMS:
                    bDone = TRUE;
                    bResult = TRUE;
                    break;
    
                 // we have got an entry
                case ERROR_SUCCESS:
    
                    // don't delete cookie entry
                    if (!(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY))
    
                     DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
    
                    // get ready for next entry
                    dwTrySize = dwEntrySize;
                    if (FindNextUrlCacheEntry(hCacheDir, lpCacheEntry, &dwTrySize))
                        dwError = ERROR_SUCCESS;
    
                    else
                    {
                        dwError = GetLastError();
                        dwEntrySize = dwTrySize; // use new size returned
                    }
                    break;
    
                // unknown error
                default:
                    bDone = TRUE;
                    break;
            }
    
            if (bDone)
            {
                delete [] lpCacheEntry;
                if (hCacheDir)
                    FindCloseUrlCache(hCacheDir);
    
            }
        } while (!bDone);
        return bResult;
    }
    /*
    UINT download_ThreadProc(void* pv)
    {
    	CDaxomatLOGGERDlg* pDlg = (CDaxomatLOGGERDlg*) pv;
        pDlg->Worker_downloadThreadProc();
    	pDlg->MessageBox("TEST 123");
        return 0;
    }
    
    void CDaxomatLOGGERDlg::Worker_downloadThreadProc()
    {
    
    }
    */
    
    void CDaxomatLOGGERDlg::start_download() 
    {
       CWinThread* pThread = AfxBeginThread(download_thread, this, THREAD_PRIORITY_HIGHEST, 1);
    }
    
    void CDaxomatLOGGERDlg::Automatik_Modus() 
    {
    	show_blank=false;
    //	SetTimer( 1, 1000, NULL);
    	CDaxomatLOGGERDlg::start_download();
    }
    
    UINT CDaxomatLOGGERDlg::download_thread(LPVOID pParam)
    {
    	CDaxomatLOGGERDlg* pDlg = (CDaxomatLOGGERDlg*) pParam;
    
    	while(true){
    		if(!pDlg->lock_download){
    
    				// Löschen des Cache
    				pDlg->CDaxomatLOGGERDlg::DelTempFiles();
    
    				// Änderung der Nachricht in der StatusBar
    				pDlg->m_StatusBar->SetText(("Empfange Daten ..."),0, 0);
    
    				// Hier der Download
    				HRESULT   hr;
    				CString   sURL, sFile;
    
    				sURL =	"http://www.daxomat.de/charts/dax_rt_kurz.jpg";
    				sFile=	pDlg->strPfadl;
    
    				hr = URLDownloadToFile ( NULL, sURL, sFile, 0, 0);
    
    				if(SUCCEEDED(hr)){
    					Sleep(4000);
    					pDlg->CDaxomatLOGGERDlg::Bild_laden();
    					pDlg->m_StatusBar->SetText(("Daten aktualisiert!"),0, 0);
    				}else{
    					pDlg->m_StatusBar->SetText(("Fehler bei der Übertragung!"),0, 0);
    				}
    
    				pDlg->test++;
    				CString a; a.Format("%i",pDlg->test);
    				pDlg->m_StatusBar->SetText((a),0, 0);
    
    		}
    
    	// Zeit bis zum erneuten Aufruf
    	Sleep(10000);
    	}
    
    return 0;
    }
    
    void CDaxomatLOGGERDlg::Bild_laden(){
    
    		LPCTSTR Pfad = strPfadl;	USES_CONVERSION;
    		HRESULT hr = OleLoadPicturePath(const_cast<LPOLESTR>(T2COLE(Pfad)), 0, 0, 0, IID_IPicture,(void **)&m_bild);
    
    		if(SUCCEEDED(hr)&&m_bild != NULL){
    			CDaxomatLOGGERDlg::OnPaint();
    		}else{
    			m_StatusBar->SetText(("ERROR: FILE NOT FOUND!"),0, 0);
    		}
    }
    
    void CDaxomatLOGGERDlg::OnTimer(UINT nIDEvent) 
    {
    	CDaxomatLOGGERDlg::start_download();
    	CDialog::OnTimer(nIDEvent);
    }
    


  • Hi,

    meines Wissens nach darfst Du mit von CWnd abgeleiteten Klassen nur aus dem
    Thread heraus hantieren, von dem dieser erzeugt worden sind.

    Deinem Code entnehme ich, dass Du Dich daran scheinbar nicht hältst.

    As a general rule, a thread can access only MFC objects that it created. This is because temporary and permanent Windows handle maps are kept in thread local storage to help maintain protection from simultaneous access from multiple threads.



  • Danke für den Hinweis, wusste ich nicht.
    Ich bin mal gespannt, ob das Problem damit tatsächlich schon gelöst ist.

    Schönen Abend noch,
    Michael


Anmelden zum Antworten