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