Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Funktion - Programmstart

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ] [ 5 ]
020
03.07.2004, 15:59 Uhr
Spacelord
Hoffnungsloser Fall


Wir reden da aneinander vorbei .
WaitForInputIdle wartet bis der Thread der das erste Fenster,des Prozesses dessen Handle du übergibst,keine Eingabeverarbeitung mehr hat und in nen Idle Zustand übergeht.Das ist bei dem "Neustart" einer Anwendung aber exakt nachdem alle Initialisierungen ausgeführt sind.Somit kannst du WaitForInputIdle nutzen um zu warten bis der Dialog auf den du zugreifen willst bereit ist.

Hier ist nen klitzekleines dreckiges Beispiel....
Einfach ne Dialoganwendung erstellen und die relevanten Stellen(Threadfunktion und Threadaufruf) einfügen.

C++:
// foo.cpp : Legt das Klassenverhalten für die Anwendung fest.
//

#include "stdafx.h"
#include "foo.h"
#include "fooDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//***************************************************************
//Prototyp Threadfunktion
UINT func(LPVOID arg);
//*****************************************************************

/////////////////////////////////////////////////////////////////////////////
// CFooApp

BEGIN_MESSAGE_MAP(CFooApp, CWinApp)
    //{{AFX_MSG_MAP(CFooApp)
        // 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()

/////////////////////////////////////////////////////////////////////////////
// CFooApp Konstruktion

CFooApp::CFooApp()
{
    // ZU ERLEDIGEN: Hier Code zur Konstruktion einfügen
    // Alle wichtigen Initialisierungen in InitInstance platzieren
}

/////////////////////////////////////////////////////////////////////////////
// Das einzige CFooApp-Objekt

CFooApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CFooApp Initialisierung

BOOL CFooApp::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

    AfxBeginThread((AFX_THREADPROC)func,
        NULL,THREAD_PRIORITY_NORMAL,0,0,NULL);

    //Aufwendige Initialisierungen simulieren
    Sleep(2000);

    CFooDlg 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;
}


UINT func(LPVOID arg)
{
    //Warten dass der Dialog gezeichnet ist und alle Initialisierungen abgeschlossen sind
    WaitForInputIdle(GetCurrentProcess(),INFINITE);
    HWND hDlg=(AfxGetApp()->GetMainWnd())->m_hWnd;
    AfxMessageBox("Dialog gezeichnet,Idle erreicht!\nNach OK wird der Dialog nach 2 Sekunden geschlossen",MB_OK,0);
    Sleep(2000);
    //Dialog schliessen
    ::PostMessage(hDlg,WM_CLOSE,NULL,NULL);

    return 0;
}





Bevor der Dialog erstellt wird ist nen Sleep Aufruf,damit simuliere ich Initialisierungen.Jetzt kannst du mal in der Threadfunktion WaitForInputIdle auskommentieren um dir den Effekt anzusehen

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
021
04.07.2004, 14:29 Uhr
Spacelord
Hoffnungsloser Fall


Hab mir jetzt mal den ganzen Thread durchgelesen.
Also um die Controls des Dialogs erst anzuzeigen nachdem die Fortschrittsanzeige "durchgelaufen" ist könnte man etwa so ne Lösung nehmen.(Wertet keinerlei Fehler aus und verlässt sich auch darauf das sonst nichts mit dem Hauptdialog passiert).
Also das Ganze ist immer noch in nem eigenen Thread der in der App Klasse vor dem DoModal des Hauptdialogs gestartet wird.Ich finde halt,weil das beim Start ne einmalige Geschichte ist sollte man deshalb nicht in der onPaint Methode rumzaubern...

Im Grunde hat sich zu dem Beispiel oben nur die Threadfunktion geändert.

C++:
UINT func(LPVOID arg)
{
    //Warten dass der Dialog gezeichnet ist und alle Initialisierungen abgeschlossen sind
    WaitForInputIdle(GetCurrentProcess(),INFINITE);
    CProgressCtrl &temp =((CFooDlg*)((CFooApp*)AfxGetApp()->GetMainWnd()))->m_Progress;
    temp.SetPos(0);
    temp.SetRange(0,100);
    temp.SetStep(1);
    while(temp.GetPos() < 100)
    {
        temp.StepIt();
        Sleep(5);
    }

    HWND hDlg=(AfxGetApp()->GetMainWnd())->m_hWnd;

    //IDs der Controls:IDOK,IDCANCEL ist wohl klar
    //IDC_PROGRESS1 ist die Fortschrittsanzeige
    HWND ButtonOK = GetDlgItem(hDlg,IDOK);
    HWND ButtonCANCEL = GetDlgItem(hDlg,IDCANCEL);
    HWND Progress = GetDlgItem(hDlg,IDC_PROGRESS1);
    ShowWindow(Progress,SW_HIDE);
    ShowWindow(ButtonOK,SW_SHOW);
    ShowWindow(ButtonCANCEL,SW_SHOW);

    return 0;
}





Mit nem Extradialog könnte es eventuell so aussehen.
Erstmal hab ich ne neue Dialogresource erstellt auf der nur die Fortschrittsanzeige platziert ist.Dazu wurde dann die Klasse generiert die bei mir Bla heisst.
Wie gehabt wird der Thread über AfxBeginThread vor DoModal gestartet.

Die neue Threadfunktion:


C++:
UINT func(LPVOID arg)
{
    //Bla ist eine Dialogklasse die nur eine Fortschrittsanzeige hat
    Bla myStart ;
    myStart.Create(IDD_DIALOG1,NULL);
    myStart.ShowWindow(SW_SHOW);
    //m_startProg ist das CProgressCtrl Member von class Bla
    (myStart.m_startProg).SetPos(0);
    (myStart.m_startProg).SetRange(0,100);
    (myStart.m_startProg).SetStep(1);
    
    while((myStart.m_startProg).GetPos() < 100)
    {
        (myStart.m_startProg).StepIt();
        Sleep(5);
    }
    //Ist der Hauptdialog fertig initialisiert?
    WaitForInputIdle(GetCurrentProcess(),INFINITE);
    //Startdialog zerstören
    myStart.DestroyWindow();

    return 0;
}




Also wie gesagt,die Beispiele gehen einfach davon aus dass alles "glatt" geht!
In ner ernsthaften Version solltest du Rückgabewerte schon auswerten.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
022
04.07.2004, 15:01 Uhr
t10ottoo



Hi,

danke erstmal für deine Bemühungen, aber irgendwie will das nicht klappen. Es dauert zwar zwei Sekunden, bis er den Dialog öffnet, aber dann passiert auch nix weiter, also er zeigt nicht die Statusleite an. Die einzige Veränderung, die ich feststellen konnte, sind die 2 Sekunden Verzögerung
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
023
04.07.2004, 15:43 Uhr
Spacelord
Hoffnungsloser Fall


Ist jetzt schwer zu sagen wo es bei dir hängt.
Hast du mal kontrolliert ob der Thread wirklich gestartet wird?Rückgabewert geprüft,MessageBox am Thread Anfang etc. probiert?
Poste doch mal den Code deiner von WinApp abgeleiteten Klasse.
Ich kann dir per Mail beide Versionen des Projekts schicken.Die funktionieren einwandfrei aber es wäre natürlich im Sinne eines Forums die Problemlösung allen zugänglich zu machen.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
024
04.07.2004, 15:56 Uhr
t10ottoo



Jo, man sollte das schon hier posten
Also mit der MessageBox gehts, allerdings ist die MessageBox hinter dem Dialog, also muss ich den Dialog erstmal minimieren, damit ich die MessageBox sehe, weiß net, ob dir das zur Fehlerbeseitigung weiterhilft.

Hier ist mal der Code, den ich bei der ...App hinzugefügt habe...
Also mein Hauptdialog, wo auch die Progressbar dann erstmal ablaufen soll, heißt "Vorratsprogramm":

C++:
//Prototyp Threadfunktion
UINT func(LPVOID arg);


Das steht in der Vorratsprogramm.cpp, die bekomme ich, wenn ich auf "CVorratsprogrammApp" klicke.

Weiter unten steht dann das:

C++:
BOOL CVorratsprogrammApp::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

    AfxBeginThread((AFX_THREADPROC)func,NULL,THREAD_PRIORITY_NORMAL,0,0,NULL);
    
    // Aufwendige Initialisierungen simulieren
    Sleep(2000);
[.....]



Und ganz unten ist die Funktion:

C++:
UINT func(LPVOID arg)
{
    //Warten dass der Dialog gezeichnet ist und alle Initialisierungen abgeschlossen sind
    WaitForInputIdle(GetCurrentProcess(),INFINITE);
    CVorratsprogrammDlg vorrat;
    CProgressCtrl &progress=((CVorratsprogrammDlg*)((CVorratsprogrammApp*)AfxGetApp()->GetMainWnd()))->progress;
    progress.SetPos(0);
    progress.SetRange(0,100);
    progress.SetStep(1);
    while(progress.GetPos() < 100)
    {
        progress.StepIt();
        Sleep(5);
    }

    HWND hDlg=(AfxGetApp()->GetMainWnd())->m_hWnd;

    HWND ButtonOK = GetDlgItem(hDlg,IDOK);
    HWND ButtonCANCEL = GetDlgItem(hDlg,IDCANCEL);
    HWND Progress = GetDlgItem(hDlg,IDC_STATUS);
    ShowWindow(Progress,SW_HIDE);
    ShowWindow(ButtonOK,SW_SHOW);
    ShowWindow(ButtonCANCEL,SW_SHOW);

    return 0;
}


Meine Progressbar hat die Variable "progress" und sie selber heißt "IDC_STATUS"

Hab mich nur an deinem Code orientiert, sollte eigentlich richtig sein...

Gruß
Thomas

Dieser Post wurde am 04.07.2004 um 15:58 Uhr von t10ottoo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
025
04.07.2004, 16:29 Uhr
Spacelord
Hoffnungsloser Fall


Vielleicht ist es sinnvoll wenn du mir mal dein Projekt zuschickst.
(aber bitte ohne Debug und Release Ordner )
Was mir in deinem Code auffällt ist:

C++:
CVorratsprogrammDlg vorrat;



Ist sinnlos aber auch harmlos.....
Also momentan kann ich mir das nicht erklären.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
026
04.07.2004, 16:56 Uhr
t10ottoo



Ok, hier hab ich das mal hochgeladen:

Vorratsprogramm

Hoffentlich steigtst du da durch

<edit>
Hab grad gemerkt, dass bei der Version, die ich hochgeladen habe, die zwei Zeilen auskommentiert sind, hab das aber nur gemacht, dass ich net immer 2 Sekunden warten muss, da ich ja schon das andere weitermach. Also net wundern

Dieser Post wurde am 04.07.2004 um 17:37 Uhr von t10ottoo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
027
05.07.2004, 13:09 Uhr
Spacelord
Hoffnungsloser Fall


OK,
also der Fehler warum du die Statusleiste nicht siehst liegt in deiner visibleAll Methode.
Da setzt du deine Fortschritsanzeige auf SW_HIDE.
Du musst bedenken das OnInitDialog vor(!!) dem Code aus dem Thread ausgeführt wird.
Wenn du die echte Initialisierung überbrücken möchtest bietet sich ohnehin eher die Variante mit dem Extradialog an.
Was momentan passiert ist ja nur Augenwischerei....

1.Entfern den Aufruf von visibleAll aus deiner OnInitDialog
2.Setz in die MessageMap des Dialogs

C++:
ON_MESSAGE(WM_USER+11,visibleAll)


Nicht in die generierten einfügen!!
3.Änder die Threadfunktion folgendermassen ab:


C++:
UINT func(LPVOID arg)
{
    //Warten dass der Dialog gezeichnet ist und alle Initialisierungen abgeschlossen sind
    WaitForInputIdle(GetCurrentProcess(),INFINITE);
    CVorratsprogrammDlg vorrat;
    CProgressCtrl &progress =((CVorratsprogrammDlg*)((CVorratsprogrammApp*)AfxGetApp()->GetMainWnd()))->progress;
    progress.SetPos(0);
    progress.SetRange(0,100);
    progress.SetStep(1);
    while(progress.GetPos() < 100)
    {
        progress.StepIt();
        Sleep(5);
    }

    HWND hDlg=(AfxGetApp()->GetMainWnd())->m_hWnd;

    ::PostMessage(hDlg,WM_USER+11,0,0);

    return 0;
}



Das Sleep in der InitInstance der App Klasse brauchst du übrigens garnicht,das war nur zur Demonstration .
Wie gesagt die schönere Lösung wäre die mit dem Extradialog weil das dann wirklich während der Initialisierung angezeigt wird und nicht danach!!

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
028
05.07.2004, 13:21 Uhr
t10ottoo



Hi,

also erstmal ein großes Dankeschön an dich, ist ja echt krass, was du hier so leistest

Aber ein Problem hab ich nun noch (wär ja sonst langweilig )

Diese Zeile hier:

Code:
ON_MESSAGE(WM_USER+11,visibleAll);



Weiß net, wo ich die hinpacken soll..
Wenn ich die, wie du sagst, in die MessageMap des Dialogs setz, das ist doch dann in der VorratsprogrammDlg.h Datei oder?
Also hier rein:

C++:
    // Generierte Message-Map-Funktionen
    //{{AFX_MSG(CVorratsprogrammDlg)
    ON_MESSAGE(WM_USER+11,visibleAll);
        ........


Aber da bekomm ich dann nen paar Fehler

<edit>
Huch, nun gehts Hatte es anner falschen Stelle

VIELEN DANK *keks geb*

Noch ne kurze Frage:
Hab hier geschaut, wie ich die Schrift in er der Progressbar ändern kann, aber nix richtiges gefunden, also ich lese ja verschiedene Dateien ein, und in der Progressbar soll dann auch die Datei stehen, die er einliest. Klar kann man das nicht synchron machen, weil er sie ja viel zu schnell einliest, also muss ich ein wenig schummeln und selbst z.B. alle 20% den Text ändern. Aber wie kann ich der Progressbar nen Text zuweisen?

Dieser Post wurde am 05.07.2004 um 13:48 Uhr von t10ottoo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
029
05.07.2004, 13:51 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


ich glaub gar nich aber du kannst einfach nen textfeld rüberpacken und da was reinschreiben...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ] [ 5 ]     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: