non modal Dialog in einem Thread createn?
-
hi,
ich habs mal versucht...jedoch mit mehr oder weniger erfolg;-)
was fehlt mir noch?...das müsste man doch bald mal zum laufen bekommen.. *hrrr*
sorry für den vielen code...ich post lieber alles bevor unklarheiten entstehen...bye
// testDlg.h : Headerdatei // #pragma once #include "Send_Dialog.h" #include <vector> #include <iostream> using namespace std; class THREADCLASS; // CtestDlg Dialogfeld class CtestDlg : public CDialog { // Konstruktion public: CtestDlg(CWnd* pParent = NULL); // Standardkonstruktor ~CtestDlg(); // Dialogfelddaten enum { IDD = IDD_TEST_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung // Implementierung protected: HICON m_hIcon; // Generierte Funktionen für die Meldungstabellen virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedButtonopenDialog(); public: vector<Send_Dialog*> m_vec; THREADCLASS *_param; }; class THREADCLASS : public CWinThread { public: CtestDlg* _this; };
// testDlg.cpp : Implementierungsdatei // // includes.... HANDLE h_open_dialog; void ThreadFunction(void *pParam); void createDebugConsole() { AllocConsole(); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); freopen("CONIN$", "r", stdin); } //.......sachen vom CAboutDlg //.......sachen vom CAboutDlg BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CtestDlg Dialogfeld CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/) : CDialog(CtestDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); h_open_dialog = CreateEvent(NULL, FALSE, FALSE, NULL); _param = new THREADCLASS; _param->_this = this; } CtestDlg::~CtestDlg() { delete _param; } void CtestDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CtestDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(ID_Button_open_Dialog, OnBnClickedButtonopenDialog) END_MESSAGE_MAP() // CtestDlg Meldungshandler BOOL CtestDlg::OnInitDialog() { CDialog::OnInitDialog(); //....initialisierungen........ // TODO: Hier zusätzliche Initialisierung einfügen AfxBeginThread (ThreadFunction, _param); createDebugConsole(); return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten } //....void CtestDlg::OnSysCommand(UINT nID, LPARAM lParam) //....void CtestDlg::OnPaint() //....HCURSOR CtestDlg::OnQueryDragIcon() void CtestDlg::OnBnClickedButtonopenDialog() { // TODO: Add your control notification handler code here SetEvent(h_open_dialog); } void ThreadFunction(void *pParam) { WaitForSingleObject(h_open_dialog, INFINITE); CtestDlg *ptr = static_cast<CtestDlg*>(pParam); // Dialog-Objekt erstellen ptr->m_vec.push_back(new Send_Dialog(ptr)); // nicht modalen Dialog erstellen und anzeigen ptr->m_vec[ptr->m_vec.size()-1]->SetForegroundWindow(); ptr->m_vec[ptr->m_vec.size()-1]->ShowWindow(SW_NORMAL); while(1) { Sleep(100); } }
error:
Compiling... testDlg.cpp c:\testDlg.cpp(120) : error C2665: 'AfxBeginThread' : none of the 2 overloads can convert parameter 1 from type 'void (__cdecl *)(void *)' c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxwin.h(4105): could be 'CWinThread *AfxBeginThread(AFX_THREADPROC,LPVOID,int,UINT,DWORD,LPSECURITY_ATTRIBUTES)' c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxwin.h(4108): or 'CWinThread *AfxBeginThread(CRuntimeClass *,int,UINT,DWORD,LPSECURITY_ATTRIBUTES)' while trying to match the argument list '(void (__cdecl *)(void *), THREADCLASS *)'
-
Dan McHould schrieb:
Hi...
Hab das noch nie anders probiert...Gibt's da einen Grund, warum du nicht mit der AFX was machen willst?
Ah ja, was ich noch gesehen habe: Du hast jetzt das Create im Konstruktor deiner Hauptklasse...Muss das so sein? Ich dachte mir eben, dass du von deiner Hauptklasse aus einen zweiten Dialog (non-modal) aufrufst, welcher dann in einem Thread läuft.
Oder ist das anders?hi,
vielleicht, da mir das mit AFX zu komplex erscheint...
Grund warum create im konstr. der hauptklass ist:
Im Beschrieb musst du ja im Konstruktor von deiner Dialogklasse das Dialogfeld Createn...steht doch auch auf der codeproject seite so...wo soll dann das create hin?bei mir läuft es so ab:
ich arbeite ja noch mit sockets...dh wenn ich auf dem socket was bestimmtest empfange das passiert im thread dann muss ich einen neuen non modal dialog aufmachen...das beispiel hier hab ich nur mal mit dem button gemacht um das zu vereinfachen...damit es mal läuft irgendwann*g*cu
-
ps.: und wie viel non modal dialoge ich erstelle und anzeige, hängt nur davon an was ich im thread am socket empfange...
cu
-
marko. schrieb:
Grund warum create im konstr. der hauptklass ist:
Im Beschrieb musst du ja im Konstruktor von deiner Dialogklasse das Dialogfeld Createn...steht doch auch auf der codeproject seite so...wo soll dann das create hin?Willst du bei jedem Socketempfang einen neuen Hauptdialog erstellen? Oder ist der nicht modale Dialog ein anderer bzw. ein zweiter?
Theoretisch dürfte das nochmalige Aufrufen des Hauptdialogs gehen...Muss aber auch zuerst auschecken.Auf Codeproject steht das Create aber im Konstruktor des aufzurufenden, zweiten Dialogfelds...
Ich poste dir am besten doch mal das Wichtigste von meinem Demoprojekt
// DialogThread.h : Haupt-Header-Datei für die Anwendung DIALOGTHREAD // #if !defined(AFX_DIALOGTHREAD_H__CBD00115_76F0_48AB_A794_2E7D73EDD68B__INCLUDED_) #define AFX_DIALOGTHREAD_H__CBD00115_76F0_48AB_A794_2E7D73EDD68B__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif #include "resource.h" // Hauptsymbole ///////////////////////////////////////////////////////////////////////////// // CDialogThreadApp: // Siehe DialogThread.cpp für die Implementierung dieser Klasse // class CDialogThreadApp : public CWinApp { public: CDialogThreadApp(); CWinThread* m_pThread[5]; // Überladungen // Vom Klassenassistenten generierte Überladungen virtueller Funktionen //{{AFX_VIRTUAL(CDialogThreadApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL // Implementierung //{{AFX_MSG(CDialogThreadApp) // HINWEIS - An dieser Stelle werden Member-Funktionen vom Klassen-Assistenten eingefügt und entfernt. // Innerhalb dieser generierten Quelltextabschnitte NICHTS VERÄNDERN! //}}AFX_MSG DECLARE_MESSAGE_MAP() }; extern CDialogThreadApp theApp; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein. #endif // !defined(AFX_DIALOGTHREAD_H__CBD00115_76F0_48AB_A794_2E7D73EDD68B__INCLUDED_)
// DialogThread.cpp : Legt das Klassenverhalten für die Anwendung fest. // #include "stdafx.h" #include "DialogThread.h" #include "DialogThreadDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDialogThreadApp BEGIN_MESSAGE_MAP(CDialogThreadApp, CWinApp) //{{AFX_MSG_MAP(CDialogThreadApp) // HINWEIS - Hier werden Mapping-Makros vom Klassen-Assistenten eingefügt und entfernt. // Innerhalb dieser generierten Quelltextabschnitte NICHTS VERÄNDERN! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDialogThreadApp Konstruktion CDialogThreadApp::CDialogThreadApp() { // ZU ERLEDIGEN: Hier Code zur Konstruktion einfügen // Alle wichtigen Initialisierungen in InitInstance platzieren } ///////////////////////////////////////////////////////////////////////////// // Das einzige CDialogThreadApp-Objekt CDialogThreadApp theApp; ///////////////////////////////////////////////////////////////////////////// // CDialogThreadApp Initialisierung BOOL CDialogThreadApp::InitInstance() { AfxEnableControlContainer(); // Standardinitialisierung // Wenn Sie diese Funktionen nicht nutzen und die Größe Ihrer fertigen // ausführbaren Datei reduzieren wollen, sollten Sie die nachfolgenden // spezifischen Initialisierungsroutinen, die Sie nicht benötigen, entfernen. #ifdef _AFXDLL Enable3dControls(); // Diese Funktion bei Verwendung von MFC in gemeinsam genutzten DLLs aufrufen #else Enable3dControlsStatic(); // Diese Funktion bei statischen MFC-Anbindungen aufrufen #endif CDialogThreadDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // ZU ERLEDIGEN: Fügen Sie hier Code ein, um ein Schließen des // Dialogfelds über OK zu steuern } else if (nResponse == IDCANCEL) { // ZU ERLEDIGEN: Fügen Sie hier Code ein, um ein Schließen des // Dialogfelds über "Abbrechen" zu steuern } // Da das Dialogfeld geschlossen wurde, FALSE zurückliefern, so dass wir die // Anwendung verlassen, anstatt das Nachrichtensystem der Anwendung zu starten. return FALSE; }
// DialogThreadDlg.h : Header-Datei // #if !defined(AFX_DIALOGTHREADDLG_H__4A95B482_54CF_4202_B7ED_C05130448FB6__INCLUDED_) #define AFX_DIALOGTHREADDLG_H__4A95B482_54CF_4202_B7ED_C05130448FB6__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 ///////////////////////////////////////////////////////////////////////////// // CDialogThreadDlg Dialogfeld (HAUPTDIALOGFELD!!!) class CDialogThreadDlg : public CDialog { // Konstruktion public: CDialogThreadDlg(CWnd* pParent = NULL); // Standard-Konstruktor // Dialogfelddaten //{{AFX_DATA(CDialogThreadDlg) enum { IDD = IDD_DIALOGTHREAD_DIALOG }; // HINWEIS: der Klassenassistent fügt an dieser Stelle Datenelemente (Members) ein //}}AFX_DATA // Vom Klassenassistenten generierte Überladungen virtueller Funktionen //{{AFX_VIRTUAL(CDialogThreadDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung //}}AFX_VIRTUAL // Implementierung protected: HICON m_hIcon; // Generierte Message-Map-Funktionen //{{AFX_MSG(CDialogThreadDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButton1(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein. #endif // !defined(AFX_DIALOGTHREADDLG_H__4A95B482_54CF_4202_B7ED_C05130448FB6__INCLUDED_)
// DialogThreadDlg.cpp : Implementierungsdatei Hauptdialogfeld // #include "stdafx.h" #include "DialogThread.h" #include "DialogThreadDlg.h" #include "MyThread.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) // Keine Nachrichten-Handler //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDialogThreadDlg Dialogfeld CDialogThreadDlg::CDialogThreadDlg(CWnd* pParent /*=NULL*/) : CDialog(CDialogThreadDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDialogThreadDlg) // 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 CDialogThreadDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDialogThreadDlg) // HINWEIS: Der Klassenassistent fügt an dieser Stelle DDX- und DDV-Aufrufe ein //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDialogThreadDlg, CDialog) //{{AFX_MSG_MAP(CDialogThreadDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDialogThreadDlg Nachrichten-Handler BOOL CDialogThreadDlg::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 return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten } void CDialogThreadDlg::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 CDialogThreadDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // Gerätekontext für Zeichnen SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Symbol in Client-Rechteck zentrieren int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Symbol zeichnen dc.DrawIcon(x, y, m_hIcon); } else { 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 CDialogThreadDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CDialogThreadDlg::OnButton1() { for(int i=0;i<5;i++) theApp.m_pThread[i]=AfxBeginThread(RUNTIME_CLASS(CMyThread)); // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen }
#if !defined(AFX_MYDIALOG_H__D562F696_4331_41A1_9C86_C78148086447__INCLUDED_) #define AFX_MYDIALOG_H__D562F696_4331_41A1_9C86_C78148086447__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // MyDialog.h : Header-Datei // ///////////////////////////////////////////////////////////////////////////// // Dialogfeld CMyDialog (2., neues Dialogfeld) class CMyDialog : public CDialog { // Konstruktion public: CString m_ThreadNr; CMyDialog(CWnd* pParent = NULL); // Standardkonstruktor // Dialogfelddaten //{{AFX_DATA(CMyDialog) enum { IDD = IDD_DIALOG1 }; // HINWEIS: Der Klassen-Assistent fügt hier Datenelemente ein //}}AFX_DATA // Überschreibungen // Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen //{{AFX_VIRTUAL(CMyDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung //}}AFX_VIRTUAL // Implementierung protected: // Generierte Nachrichtenzuordnungsfunktionen //{{AFX_MSG(CMyDialog) afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnButton1(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein. #endif // AFX_MYDIALOG_H__D562F696_4331_41A1_9C86_C78148086447__INCLUDED_
// MyDialog.cpp: Implementierungsdatei (2., neues Dialogfeld) // #include "stdafx.h" #include "DialogThread.h" #include "MyDialog.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Dialogfeld CMyDialog CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/) : CDialog(CMyDialog::IDD, pParent) { //{{AFX_DATA_INIT(CMyDialog) // HINWEIS: Der Klassen-Assistent fügt hier Elementinitialisierung ein //}}AFX_DATA_INIT Create(IDD_DIALOG1,NULL); int static nr=1; CString s; char buf[10]; itoa(nr,buf,10); s="Thread #"; s+=buf; s+= " Dialog Window"; SetWindowText(s); switch(nr) { case 1:{m_ThreadNr="1";break;} case 2:{m_ThreadNr="2";break;} case 3:{m_ThreadNr="3";break;} case 4:{m_ThreadNr="4";break;} case 5:{m_ThreadNr= "5";break;} break; } // we want to be informed which thread is the current thread after 1 second SetTimer(nr,1000,NULL); nr++; } void CMyDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDialog) // HINWEIS: Der Klassen-Assistent fügt hier DDX- und DDV-Aufrufe ein //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CMyDialog, CDialog) //{{AFX_MSG_MAP(CMyDialog) ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Behandlungsroutinen für Nachrichten CMyDialog void CMyDialog::OnTimer(UINT nIDEvent) { // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen und/oder Standard aufrufen CString str= "Thread"; str+=m_ThreadNr; TextOut(NULL,0,0,str,0); //m_speaker.Speak(str); //you may delete this line if you want to hear the threads continuously KillTimer(nIDEvent); CDialog::OnTimer(nIDEvent); } void CMyDialog::OnButton1() { // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen DestroyWindow(); }
#if !defined(AFX_MYTHREAD_H__DEB7E8BC_EC49_47D6_B27F_8FCCEFB837AB__INCLUDED_) #define AFX_MYTHREAD_H__DEB7E8BC_EC49_47D6_B27F_8FCCEFB837AB__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // MyThread.h : Header-Datei // ///////////////////////////////////////////////////////////////////////////// // Thread CMyThread (Die Threadklasse, abgeleitet von CWinThread) class CMyThread : public CWinThread { DECLARE_DYNCREATE(CMyThread) protected: CMyThread(); // Dynamische Erstellung verwendet geschützten Konstruktor // Attribute public: // Operationen public: // Überschreibungen // Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen //{{AFX_VIRTUAL(CMyThread) public: virtual BOOL InitInstance(); virtual int ExitInstance(); //}}AFX_VIRTUAL // Implementierung protected: virtual ~CMyThread(); // Generierte Nachrichtenzuordnungsfunktionen //{{AFX_MSG(CMyThread) // HINWEIS - Der Klassen-Assistent fügt hier Member-Funktionen ein und entfernt diese. //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein. #endif // AFX_MYTHREAD_H__DEB7E8BC_EC49_47D6_B27F_8FCCEFB837AB__INCLUDED_
// MyThread.cpp: Implementierungsdatei (ThreadKlasse abgeleitet von CWinThread) // #include "stdafx.h" #include "DialogThread.h" #include "MyThread.h" #include "MyDialog.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMyThread IMPLEMENT_DYNCREATE(CMyThread, CWinThread) CMyThread::CMyThread() { } CMyThread::~CMyThread() { } BOOL CMyThread::InitInstance() { // ZU ERLEDIGEN: Initialisierungen für jeden Thread hier durchführen m_pMainWnd=new CMyDialog; m_pMainWnd->SetForegroundWindow(); m_pMainWnd->ShowWindow(SW_SHOW); return TRUE; } int CMyThread::ExitInstance() { // ZU ERLEDIGEN: Bereinigungen für jeden Thread hier durchführen return CWinThread::ExitInstance(); } BEGIN_MESSAGE_MAP(CMyThread, CWinThread) //{{AFX_MSG_MAP(CMyThread) // HINWEIS - Der Klassen-Assistent fügt hier Zuordnungsmakros ein und entfernt diese. //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Behandlungsroutinen für Nachrichten CMyThread
Gruz Dan
-
Willst du bei jedem Socketempfang einen neuen Hauptdialog erstellen? Oder ist der nicht modale Dialog ein anderer bzw. ein zweiter?
Theoretisch dürfte das nochmalige Aufrufen des Hauptdialogs gehen...Muss aber auch zuerst auschecken.Auf Codeproject steht das Create aber im Konstruktor des aufzurufenden, zweiten Dialogfelds...
Ich poste dir am besten doch mal das Wichtigste von meinem Demoprojekt
ich will ja nicht mehrere male den hauptdialog (CtestDlg) erstellen sondern habe 1 hauptdialog, und der thread erzeugt mehrere dialoge(Send_Dialog)...also ein anderer!!
cu
-
hi!
kannst du mir mal dein beispiel mailen an: 5aht@gmx.at ....hab das gefühl das liegt eher am compiler...hab den mvc 7.1 ...
weil das codeproject demo funzt auch nicht...beim ausführen gibs nen absturz;-(für was brauchst du das void CMyDialog::OnTimer(UINT nIDEvent ...) ?
cu
-
Hmm...
Na ja, ich habe mein Beispiel mit VC6.0 erstellt..Mal sehen, ob's klappt...
Die OnTimer Methode ist nur noch pro Forma drin...Habe da mal noch was ausprobiert...
Nur nicht irritieren lassen...Gruz Dan
-
hi,
das klappt;-) komisch*g*
warum brauchst du da ne DialogThreadDlg.h u .cpp und ne DialogThread.h u .cppMyDialog ist ja der Dialog den du beim anklicken auf den button aufmachen willst...und MyThread ist der thread...
bye...big thx!!!
-
warum brauchst du da ein:
extern CDialogThreadApp theApp;
??
cu
-
Hi...
warum brauchst du da ne DialogThreadDlg.h u .cpp und ne DialogThread.h u .cpp
DialogThread.h und .cpp ist die Klasse in der der Hauptdialog meiner Anwendung inititalisiert wird.
DialogThreadDlg.h und .cpp ist die Klasse des HAUPTDIALOGS. Meine Applikation wurde als dialogfeldbasierende Anwendung erstellt.MyDialog ist ja der Dialog den du beim anklicken auf den button aufmachen willst
Genau. Der Button liegt jedoch noch auf dem HAUPTDIALOG. Und den Code zum Button findest du in der Klasse DialogThreadDlg.
Wenn dieser Button gedrückt wird, werden 5 Threads nacheinander gestartet und JEDER EINZELNE THREAD erzeugt ein neues Dialogfeld. Jedes im jeweiligen Thread erzeugte Dialogfeld ist nicht modal und eine Instanz von der Klasse MyDialog. Jedes der Dialofelder läuft nachher IN einem separaten Thread.Das bedeutet: MyDialog ist also ein ZWEITES Dialogfeld mit einer eigenen, separaten Klasse.
warum brauchst du da ein:
C/C++ Code:
extern CDialogThreadApp theApp;Na ja, ich erzeuge eine Instanz der Klasse DialogThread global, damit ich überall auf die jeweiligen Threads Zugriff habe. Dies ist vorallem wichtig, wenn du von irgendwoher einen Thread wieder löschen musst.
Gruz
Dan
-
danke;-)
also im thread erzeuge ich einen dialog mit m_pMainWnd->ShowWindow(SW_HIDE);
wie kann ich nun aus dem hauptdialog (zb.: ich mach nen 2 button dazu, dann:) sagen m_pMainWnd->ShowWindow(SW_SHOW);???
oder vom hauptdialog aus in einem dialog irgendwas in ein textfeld schreiben?wenn das geht..perfekt;-)
cu
-
Hi
Da musste die Threads ein wenig anders erzeugen:
theApp.m_pThread[i]=(CMyThread*)AfxBeginThread(RUNTIME_CLASS(CMyThread));
Nun solltest du auf die Variablen und Instanzen der jeweiligen Threadinstanz Zugriff haben.
Also zum Beispiel das Dialogfeld im Thread 1:
theApp.m_pThread[0]->DeinDialog->ShowWindow(SW_SHOW); oder so...
Hoffe das klappt so...Probiers mal aus...
Gruz
Dan
-
hi,
du hast das CWinThread* m_pThread[5]; in der klasse CDialogThreadApp!ich brauche CWinThread* m_pThread[5]; aber in der klasse CDialogThreadDlg!!!
wie mach ich das dann am besten? ein GetParent?
cu
-
hi,
hab noch ne frage...
ich will ja daten von nem socket empfangen...das läuft in einem thread mit ner endloschleife...der thread bekommt einen pointer auf die hauptklasse...
ich lege jetzt in diesem thread neue AfxThreads an, wenn ich einen neuen dialog erzeugen will...da der thread ja nachrichtenbasierend ist, muss ich den ja nachrichten schicken, wenn ich zb in ein editfeld etwas schreiben will...
in der hauptklasse hab ich das array mit den pointern auf die threads...jedoch weiss ich da nicht wie ich da aus diesen thread, der ja einen pointer auf die hauptklasse hat ne methode zb.: void Show_Window(....) aufrufen kann, die der ThreadKlasse gehört!?wie findest du das konzept?
cu
-
du hast das CWinThread* m_pThread[5]; in der klasse CDialogThreadApp!
ich brauche CWinThread* m_pThread[5]; aber in der klasse CDialogThreadDlg!!!Das geht, wenn du eine globale Instanz deklariert hast (Von der CDialogThreadApp)
Siehe Beitrag um 10.07 von heute...ich lege jetzt in diesem thread neue AfxThreads an, wenn ich einen neuen dialog erzeugen will...da der thread ja nachrichtenbasierend ist, muss ich den ja nachrichten schicken, wenn ich zb in ein editfeld etwas schreiben will...
Musst du nicht. Initialisiere den jeweiligen Thread so, wie ich's bereits beschrieben habe (Beitrag 11.57 von heute). Dann solltest du direkt auf die jeweilige Membervariable des bestimmten Editfelds zugreifen können.
in der hauptklasse hab ich das array mit den pointern auf die threads...jedoch weiss ich da nicht wie ich da aus diesen thread, der ja einen pointer auf die hauptklasse hat ne methode zb.: void Show_Window(....) aufrufen kann, die der ThreadKlasse gehört!?
Das sollte aber möglich sein...Siehe wieder Beitrag um 10.07 von heute...
Geht da nicht irgenwie sowas wie (im Socketthread):
Wenn du das Array mit den Pointern nicht globalisierst, dann sollte doch das so gehen: DeinPtraufHauptklasse->m_pThread[2]->m_xy.Format("blah");Wenn der Socketthread immer läuft, dann kannste das glaub ich schon so machen...
Gib mir mal n'Feedback, wenn's läuft...Gruz Dan
-
ich lege jetzt in diesem thread neue AfxThreads an, wenn ich einen neuen dialog erzeugen will...da der thread ja nachrichtenbasierend ist, muss ich den ja nachrichten schicken, wenn ich zb in ein editfeld etwas schreiben will...
Musst du nicht. Initialisiere den jeweiligen Thread so, wie ich's bereits beschrieben habe (Beitrag 11.57 von heute). Dann solltest du direkt auf die jeweilige Membervariable des bestimmten Editfelds zugreifen können.
hatte heute ne diskussion mit jemanden, der sagte folgendes:
wenn du von einem Thread auf einem Formular in einem anderen Thread (bei dir der App-Thread) zugreifst, muss die sache in die Hose gehen
du kannst in einem Thread nur auf Sachen zugreifen, die auch in deinem Thread erstellt wurden
die App gehört sicherlich nciht dazu
ein ausweg wäre die Syncronisierung deines Workerthreads mit den Hauptthread
so dass die Threads gleich laufen
also als ein Thread angesehen werden können.
dann darfst du zugreifen.
die Syncronisation ist aber immer etwas schwierig.
es geht, aber wenn man das umgehen kann, vermeidet man das
weil mit einer Syncronisation natürlich auch die parallelität nicht mehr da ist
du hebs den eigentlichen zweck des Threads auf
das kann man umgehen indem man das Processmodel von Windows nutzt
alle Nachrichtenschleifen werden vom Prozess und dem App-Thread der Anwendung gesteuert. Diese müssen nciht syncronisert werden.
man muss sich das wie ein Stack vorstellen
du packst mit SendMessage eine Nachricht auf den Schleifenstapel
und die Anwendung / Formular nimmt sich die Nachrichten von unten immer nacheinander weg
das führt zu einer indirekten syncronisation ein SendMessage- Aufruf muss also nicht synconisiert werden
AndreasW folglich bleibt der Thread auch voll funktionsfähig
und wird nicht ausgebremstalso sowas:
SendMessage (EditBoxHandel, SET_TEXT, "Mein Text"); so brauchst du nciht mal nen Pointer auf das Formular mit #defin WM_MYRECIVEMESSAGE mit #define WM_MYRECIVEMESSAGE dann eine struct oder class und mit dieser WM_MYRECIVEMESSAGE an das Handle von der CWinApp-Instanz schicken (mit SendMessage) dort ein fenster aufmachen und anzeigen überlass die Organisation der Fenster dem Hauptthread ist besser CWinApp ist überigens von CWinThread abgeleitet m_hThread ist dann überigens das Handle des Hauptthreads wie kommt man aufs App-Handle?
ps.: hab deine variante noch nicht probiert, da ging vorher noch was schief!!
cu
-
hi, es funzt nun....ich sende einfach eine PostMessage aus dem thread an den Hauptdialog....PostMessage ruft eine funktion auf und der erstellt mir dann den dialog,-) geht ja viel einfacher;-) aber danke noch mal....zu viele threads sind sowieso nie gut...
cu