Forum: PC-Programmierung Visual C++ CCommandLineInfo


von Sebastian U. (sulmer)


Lesenswert?

Hey,
kurz mein Problemchen. Beim Start meiner MDI Applikation werde ich durch 
einen Dialog am Anfang aufgefordert ein neues Document zu erstellen. Ist 
es möglich, das beim Start der Applikation nicht ein neues Dokument 
erzeugt werden kann sondern ein altes geöffnet?

Soweit ich bisher gesehn hab ist dafür die Klasse

CCommandLineInfo::CCommandLineInfo()

verantwortlich, von der in der InitInstance eine neue Instanz erzeugt 
wird.
Der Konstruktor sieht folgendermaßen aus:

CCommandLineInfo::CCommandLineInfo()
{
  m_bShowSplash = TRUE;
  m_bRunEmbedded = FALSE;
  m_bRunAutomated = FALSE;
  m_nShellCommand = FileNew;
}

Nun wird nach ein paar Funktionsaufrufen die Variable m_nShellCommand 
ausgewertet und aufgrund des "FileNew" wird der Dialog erzeugt.
Dachte ganz leicht, änder ich doch einfach "FileNew" in "FileOpen".
Komischerweise weißt er mir immernoch "FileNew" zu.
Hat jmd einen Ansatz um beim Start nicht den FileNew-Dialog sondern den 
FileOpen Dialog aufzurufen?

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Ulmer wrote:
> Hey,
> kurz mein Problemchen. Beim Start meiner MDI Applikation werde ich durch
> einen Dialog am Anfang aufgefordert ein neues Document zu erstellen.

Das liegt daran, dass du mehrere Dokument Typen registriert hast.
Wie ich schon mal sagte: Ist keine so gute Idee.

> Ist
> es möglich, das beim Start der Applikation nicht ein neues Dokument
> erzeugt werden kann sondern ein altes geöffnet?

Sicher

>
> Soweit ich bisher gesehn hab ist dafür die Klasse
>
> CCommandLineInfo::CCommandLineInfo()
>
> verantwortlich, von der in der InitInstance eine neue Instanz erzeugt
> wird.
> Der Konstruktor sieht folgendermaßen aus:

Der ist herzlich uninteressant.

Schau ins InitInstance. Gleich nachdem das Objekt erzeugt wurde,
wird ProcessCommandLine aufgerufen. Was denkst du macht dieser
Aufruf?

> Nun wird nach ein paar Funktionsaufrufen die Variable m_nShellCommand
> ausgewertet und aufgrund des "FileNew" wird der Dialog erzeugt.
> Dachte ganz leicht, änder ich doch einfach "FileNew" in "FileOpen".
> Komischerweise weißt er mir immernoch "FileNew" zu.

Klar. Weil ProcessCommandLine den FileNew hineinschreibt, weil auf der
Command Line keine Datei angegeben ist.

> Hat jmd einen Ansatz um beim Start nicht den FileNew-Dialog sondern den
> FileOpen Dialog aufzurufen?

Ist doch einfach.
In der InitInstance:
1
    CCommandLineInfo cmdInfo;
2
//  ParseCommandLine(cmdInfo);
3
4
    cmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
5
    cmdInfo.m_strFileName = "C:\\test.dat";
6
7
    // Dispatch commands specified on the command line
8
    if (!ProcessShellCommand(cmdInfo))
9
      return FALSE;

Wenn du aber sowieso immer eine Datei öffnen willst und daher
auf die Übergabe eines Dateinamens verzichten willst (was besonders
praktisch ist, wenn die Dateiendung deiner Dateien mit deinem
Programm verknüpft sind, dann reicht ein Doppelklick auf die
Datendatei und dein Programm startet und lädt diese Datei)
dann brauchst du im Grunde überhaupt keine Command Line Auswertung
mehr, und kannst daher den Open direkt machen:
1
  /*
2
    CCommandLineInfo cmdInfo;
3
    ParseCommandLine(cmdInfo);
4
5
    cmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
6
    cmdInfo.m_strFileName = "C:\\test.dat";
7
8
    // Dispatch commands specified on the command line
9
    if (!ProcessShellCommand(cmdInfo))
10
      return FALSE;
11
*/
12
    OpenDocumentFile( "C:\\test.dat" );

Anstelle des fixen Dateinamens hindert dich nun nichts und niemand
daran, vorher mit einem FileOpenDialog einen Filenamen abzufragen.

Andere Möglichkeit.
Anstelle von FileOpen weist du der CommandLineInfo den Befehl
FileNothing zu, damit fährt dein Programm hoch, das Hauptfenster
zeigt sich und ansonsten passiert nichts. Wenn man das dann noch
damit kombiniert, dass ProcessCommandLine ein FileNew hinterlässt,
wenn es auf der CommandLine keinen Befehl entdeckt hat, hat man
das beste aus 2 Welten: Auf der einen Seite ist die App beim
Hochfahren ruhig. Auf der anderen Seite funktioniert DDE immer
noch.
1
    CCommandLineInfo cmdInfo;
2
    ParseCommandLine(cmdInfo);
3
4
    if( cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew )
5
      cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
6
7
    // Dispatch commands specified on the command line
8
    if (!ProcessShellCommand(cmdInfo))
9
      return FALSE;

von Sebastian U. (sulmer)


Lesenswert?

DokumentTypen hab ich nur eins. Hab aber 2 Views, die beide für dieses 
Dokument registiert sind. Und nun frägt er halt welchen View er öffnen 
soll.
Dein Ansatz ist schon logisch, aber so müsste ich den Dateinamen direkt 
im Code angeben, was meist ziemlich doof ist.
Eigentlich soll er den einfachen FileOpen Dialog öffnen.

Hab nun einfach den Dialog rausgenommen, reicht mir eigentlich. Möchte 
nur nicht immer am Anfang ein neues Dokument haben.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Ulmer wrote:

> DokumentTypen hab ich nur eins.
Dann würde der Document Manager nicht nachfragen

> Und nun frägt er halt welchen View er öffnen
> soll.

Ne. er fragt welchen DokumentTyp er öffnen soll.
Für jedes Dokument ist bei der Anlage des Document Templates
sowieso der zu verwendende View festgelegt worden.

(*) Moment, nicht das ich da jetzt was falsches behaupte. Ist
schon lange her. Muss das eben noch abklären.

> Dein Ansatz ist schon logisch, aber so müsste ich den Dateinamen direkt
> im Code angeben, was meist ziemlich doof ist.
> Eigentlich soll er den einfachen FileOpen Dialog öffnen.


Was hindert dich daran, zuvor einen FileOpenDialog hochzupappen
und nach einem Filenamen zu fragen?

>
> Hab nun einfach den Dialog rausgenommen, reicht mir eigentlich. Möchte
> nur nicht immer am Anfang ein neues Dokument haben.

Ich hab noch ein paar Ergänzungen im vorhergehenden Post vorgenommen.
Die solltest du nochmal lesen.

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger wrote:

> (*) Moment, nicht das ich da jetzt was falsches behaupte. Ist
> schon lange her. Muss das eben noch abklären.

Der Trick besteht darin, dass du den 2. View zwar in einem
DocTemplate mit dem Document verknüpfst, dieses aber nicht
beim DocumentManager registrierst.
Das Template benötigst du, damit du von einem Menükommando aus,
diesen View erzeugen kannst und der dann mit dem Document
verknüpft ist.

Und das geht so:

Im Header File der Appliktion führst du dir eine Member
Variable ein.
1
class CCommandApp : public CWinApp
2
{
3
public:
4
  CCommandApp();
5
6
// Overrides
7
  // ClassWizard generated virtual function overrides
8
  //{{AFX_VIRTUAL(CCommandApp)
9
  public:
10
  virtual BOOL InitInstance();
11
  //}}AFX_VIRTUAL
12
13
  CMultiDocTemplate* m_pScndDocTemplate;
14
15
...

In der InitInstance erzeugst du das zusätzliche Template,
registrierst es aber nicht mit AddDocTemplate
1
    ...
2
    LoadStdProfileSettings();  // Load standard INI file options (including MRU)
3
4
    // Register the application's document templates.  Document templates
5
    //  serve as the connection between documents, frame windows and views.
6
7
    CMultiDocTemplate* pDocTemplate;
8
    pDocTemplate = new CMultiDocTemplate(
9
                       IDR_COMMANTYPE,
10
                       RUNTIME_CLASS(CCommandDoc),
11
                       RUNTIME_CLASS(CChildFrame), // custom MDI child frame
12
                       RUNTIME_CLASS(CCommandView));
13
    AddDocTemplate(pDocTemplate);
14
15
    m_pScndDocTemplate = new CMultiDocTemplate(
16
                       IDR_COMMANTYPE,
17
                       RUNTIME_CLASS(CCommandDoc),
18
                       RUNTIME_CLASS(CChildFrame), // custom MDI child frame
19
                       RUNTIME_CLASS(CScndView));
20
21
    // create main MDI Frame window
22
    CMainFrame* pMainFrame = new CMainFrame;
23
    ...

In der ExitInstance wird das Template wieder gelöscht.

Dann baust du ein Menükommando ein (zum Dokument), welches in der
Applikation dafür sorgt, dass das 2. Fenster bei Bedarf vom Benutzer
geöffnet werden kann. Dazu benutzt das Dokument eine Funktion
aus der Applikation:
1
CScndView* CCommandApp::CreateScndView( CCommandDoc* pDoc )
2
{
3
  ASSERT( m_pScndDocTemplate );
4
5
  if( pDoc == NULL )
6
    return NULL;
7
8
  CFrameWnd* pFrame = m_pScndDocTemplate->CreateNewFrame( pDoc, NULL );
9
10
  if( pFrame ) {
11
    m_pScndDocTemplate->InitialUpdateFrame( pFrame, pDoc );
12
    return (CScndView *) pFrame->GetActiveView();
13
  }
14
15
  return NULL;
16
}

und der Aufruf im Document-Menühandler
1
void CCommandDoc::OnWindowScnd() 
2
{
3
  ((CCommandApp*)AfxGetApp())->CreateScndView( this );
4
}

von Sebastian U. (sulmer)


Lesenswert?

Danke für deine Antwort, hab jetzt deine Anfrage noch reingemacht. 
Funktioniert soweit gut.

von Timo (Gast)


Lesenswert?

Na, haste dein Problemchen im Griff?

Was macht eigentlich dein meeeeeega Stromverbrauch??

von Sebastian U. (sulmer)


Lesenswert?

Na klar hab ich das Problem im Griff. Was denkst du denn? ^^

Mein Stromverbrauch ist immernoch in einem akzeptierbaren Rahmen^^ 160mA 
gehn doch noch

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.