non modal Dialog in einem Thread createn?
-
hi,
ist es möglich in einem thread einen non modal dialog zu erstellen?
ich hab einen vector wo ich den pointer auf den dialog speichere, über den pointer der auf die klasse zeigt...hab ich zugriff auf den vector der public ist...problem ist der dialog steck irgendwie...;-(
was soll ich bei create angeben: Create(CDialog_send_recv::IDD) ....irgendeine ID???bye
// Dialog-Objekt erstellen ptr->m_vec[i].ptr_dialog_send_recv = new CDialog_send_recv(ptr); ptr->m_vec[i].ptr_dialog_send_recv->m_static_usernameRecv = ptr->m_vec[i].userid.c_str(); // textfeld auf Namen des users setzen // nicht modalen Dialog erstellen und anzeigen ptr->m_vec[i].ptr_dialog_send_recv->Create(CDialog_send_recv::IDD); ptr->m_vec[i].ptr_dialog_send_recv->ShowWindow(SW_NORMAL); // Dialog den namen des users geben ptr->m_vec[i].ptr_dialog_send_recv->m_Dialog_username = ptr->m_vec[i].username; // Dialog die userid des users geben ptr->m_vec[i].ptr_dialog_send_recv->m_Dialog_userid = ptr->m_vec[i].userid; // element des m_windowSendOpen vectors an pos. auf true setzen, da Dialog jetzt offen ptr->m_vec[i].dialog_send_recv_open = true;
-
Hallo...
Bin auch gerade an dem Problem. (Non Modalen Dialog in Thread erstellen)
Schau mal hier:[url]
http://www.codeproject.com/threads/threads_and_mfc.asp
[/url]Ich habs nach diesem Beitrag mal versucht, klappt nicht schlecht. Bin ich jetzt gerade am ausprobieren, wie ich Parameter übergeben kann...
[url]
http://www.c-plusplus.net/forum/viewtopic-var-t-is-111309.html
[/url]Gruz
Dan
-
hi! das funzt nicht recht..das prog stürzt ab;-( muss ich neben der IDD noch einen param abgeben....? was sagt dieser param aus, wenn man nicht abgibt ist der NULL? bei create ist der absturz;-(
bye
-
@Dan McHould:
hi, wie hast du das gemacht? hab mir das mal durchgelesen...aber funktioniert noch immer nicht...beim create stürzt es ab;-(cu
-
Hi...
Also, ich nehme an, dass du das mal genau so durchgespielt hast, wie's beschrieben steht.
Im Beschrieb musst du ja im Konstruktor von deiner Dialogklasse das Dialogfeld Createn...
Kannst du mal ein wenig Code posten und was kriegst du für eine Fehlermeldung?
Du musst den Parameter angeben. In diesem Fall ist der NULL. (Der zweite Parameter zeigt auf das Parent Window, wenn er Null ist, dann ist das Parent Window das Hauptfenster)
Schau hier:
[url]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cdialog.3a3a.create.asp
[/url]Wo hast du deinen Code hingepackt, den du gepostet hast? Befindet sich der jetzt in der Threadklasse in der InitInstance?
Gruz
-
hi,
ich habe jetzt das create im konstr.
hab hier mal das project upgeloaded: www.gerii.com/test.zip
jetzt geht im konstr. das create schief;-(
code:
CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/) : CDialog(CtestDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); h_open_dialog = CreateEvent(NULL, FALSE, FALSE, NULL); bool ret = Create(IDD_DIALOG1, NULL); } BOOL CtestDlg::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 // TODO: Hier zusätzliche Initialisierung einfügen _beginthread(thread_function, 0, this); createDebugConsole(); return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten } void CtestDlg::OnBnClickedButtonopenDialog() { // TODO: Add your control notification handler code here SetEvent(h_open_dialog); } void thread_function(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]->Create(IDD_DIALOG1, NULL); ptr->m_vec[ptr->m_vec.size()-1]->ShowWindow(SW_NORMAL); while(1) { Sleep(100); } }
cu
-
Hi...
Was bei deinem Projekt fehlt ist eine von CWinThread abgeleitete Threadklasse.
Wo ist die?
Das was du in deinem Code machst, ist ein Arbeitsthread (Worker Thread) nicht aber ein User Interface Thread...
Du musst den Thread mit dieser Methode starten:CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
Bevor du das aber machen kannst, musst du die ThreadClass erstellen und von CWinThread ableiten! Du kriegst nachher eine separate ThreadKlasse mit eigenem Message Handler...
Siehe auch:
[url]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_afxbeginthread.asp
[/url]Schau dir doch mal den Source vom Demoprojekt an, welches du auf Codeproject findest. Link siehe weiter unten....
Gruz
Dan
-
hi,
nagut...aber geht das nicht ohne AfxBeginThread? mit AfxBeginThread hab ich noch nie was gemacht, wollt eigentlich ohne dem auskommen;-)...zeig mal keines beispiel wie das meinst...pleasecu
-
ich stell mir auch gerade die frage, wie ich dann in der thread function auf dem m_vec vector der klasse CtestDlg zugreifen kann!?
irgendwie komm ich nicht recht weiter...hab wo gelesen ich muss ne message map selber schreiben...hmbye
-
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?
Wenn das nämlich so ist, dann geht das sicher nicht so...Du musst deinen Dialog schon komplett im Thread erstellen, sonst klappt das nicht...
Geh doch nochmal auf den Link, welchen ich dir bereits unten gepostet habe. Zweite Hälfte...Da gibt's eine genaue Anleitung, wie man vorzugehen hat. Ich habe das mal in einem Testprojekt ausprobiert, bevor es "ans Eingemachte ging", dies hat gut hingehauen.[url]
http://www.codeproject.com/threads/threads_and_mfc.asp
[/url]Das mit dem Zugreifen auf Variablen der Hauptklassen geht...Guck mal hier:
[url]
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39101.html
[/url]Leider habe ich keine Seite auf die ich das projekt hochladen könnte...Daher musst du dich mit der Anleitung in Englisch auf Codeproject begnügen..
Folgendes noch zum allgemeinen Ablauf (So wie's bei mir läuft):
Hauptapplikation öffnet Hauptfenster in Hauptthread -> Hauptapplikation startet neuen Thread -> THREAD startet zweiten, non modalen Dialog (in der InitInstance)-> Die Create Methode wird im Konstruktor vom zweiten Dialog platziert und wird beim Start des zweiten Dialogs durchlaufen...
Nur nicht verzweifeln, das kriegen wer schon noch irgendwie hin...
Gruz Dan
-
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