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...please

    cu



  • 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...hm

    bye



  • 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 .cpp

    MyDialog 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


Log in to reply