mikrocontroller.net

Forum: PC-Programmierung Visual C++ CCommandLineInfo


Autor: Sebastian Ulmer (sulmer)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
    CCommandLineInfo cmdInfo;
//  ParseCommandLine(cmdInfo);

    cmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
    cmdInfo.m_strFileName = "C:\\test.dat";

    // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
      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:
  /*
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    cmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
    cmdInfo.m_strFileName = "C:\\test.dat";

    // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
      return FALSE;
*/
    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.
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    if( cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew )
      cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;

    // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
      return FALSE;

Autor: Sebastian Ulmer (sulmer)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
class CCommandApp : public CWinApp
{
public:
  CCommandApp();

// Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CCommandApp)
  public:
  virtual BOOL InitInstance();
  //}}AFX_VIRTUAL

  CMultiDocTemplate* m_pScndDocTemplate;

...

In der InitInstance erzeugst du das zusätzliche Template,
registrierst es aber nicht mit AddDocTemplate
    ...
    LoadStdProfileSettings();  // Load standard INI file options (including MRU)

    // Register the application's document templates.  Document templates
    //  serve as the connection between documents, frame windows and views.

    CMultiDocTemplate* pDocTemplate;
    pDocTemplate = new CMultiDocTemplate(
                       IDR_COMMANTYPE,
                       RUNTIME_CLASS(CCommandDoc),
                       RUNTIME_CLASS(CChildFrame), // custom MDI child frame
                       RUNTIME_CLASS(CCommandView));
    AddDocTemplate(pDocTemplate);

    m_pScndDocTemplate = new CMultiDocTemplate(
                       IDR_COMMANTYPE,
                       RUNTIME_CLASS(CCommandDoc),
                       RUNTIME_CLASS(CChildFrame), // custom MDI child frame
                       RUNTIME_CLASS(CScndView));

    // create main MDI Frame window
    CMainFrame* pMainFrame = new CMainFrame;
    ...

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:
CScndView* CCommandApp::CreateScndView( CCommandDoc* pDoc )
{
  ASSERT( m_pScndDocTemplate );

  if( pDoc == NULL )
    return NULL;

  CFrameWnd* pFrame = m_pScndDocTemplate->CreateNewFrame( pDoc, NULL );

  if( pFrame ) {
    m_pScndDocTemplate->InitialUpdateFrame( pFrame, pDoc );
    return (CScndView *) pFrame->GetActiveView();
  }

  return NULL;
}

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

Autor: Sebastian Ulmer (sulmer)
Datum:

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

Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, haste dein Problemchen im Griff?

Was macht eigentlich dein meeeeeega Stromverbrauch??

Autor: Sebastian Ulmer (sulmer)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.