Brauche Hilfe bei Änderung einer Befehlszeile



  • Hallo,

    ich bräuchte Hilfe bei einem Startprogramm.

    Problemstellung:
    Ich arbeite mit einem Programm namens Dampsoft. Dieses ist ein Praxisverwaltungsprogramm. Zum Erstellen von Röntgenbildern wird ein externes Programm benötigt. Dieses heißt CDR Dicom. Der Aufruf des Röntgenprogramms erfolgt über das Verwaltungsprogramm und übergibt über einen Startparameter die folgenden drei Infos, Patientenname, Patientenvorname und Patientennummer, so daß das Röntgenprogramm nach dem Start automatisch den richtigen Patienten anzeigt. Da das Röntgenprogramm leider keinen Kommandozeilenaufruf versteht, hat die Herstellerfirma ein sog. Bridging-Programm beigelegt, incl. Quellcode und aller benötigten Dateien, damit es individuell angepaßt werden kann. Das Bridging-Programm heißt CDRStart.exe und in seiner jetztigen Form hat es folgende Syntax beim Aufruf:

    CDRStart /LastName Smith /FirstName John /IDNumber 12345,

    wobei Smith, John und 12345 sich halt jeweils entsprechend des Patienten ändert.

    nun kommt leider unser Praxisprogramm mit diesem Aufruf nicht zurecht, da der Aufruf der immer gleichen Bezeichnung LastName, FirstName und IDNumber Probleme bereitet.

    Ideal wäre eine Befehlszeile wie folgt:

    CDRStart /Smith /John /12345

    damit wäre es möglich, direkt aus dem Verwaltungsprogramm das Röntgenprogramm zu starten und direkt den Patienten angezeigt zu bekommen.

    Der Quellcode der Datei CDRStart.exe listet sich in der Datei CDRStart.cpp wie folgt:

    ///////////////////////////////////////////////////////////////////////////////////////////////
    // CDRStart.cpp
    // Program to launch CDR and open patient exams with supplied parameters
    ///////////////////////////////////////////////////////////////////////////////////////////////

    #include "stdafx.h"
    #include <string>
    #import "CDR.tlb" no_namespace named_guids
    #import "CDRData.tlb" named_guids

    using namespace std;

    // Our parameters
    const TCHAR PARAM_LAST_NAME[] = _T("/Lastname");
    const TCHAR PARAM_FIRST_NAME[] = _T("/Firstname");
    const TCHAR PARAM_ID_NUMBER[] = _T("/IDNumber");

    TCHAR *GetParam(LPCTSTR lpCmdLine, LPCTSTR lpParam);

    // Main entry point for our application
    int APIENTRY _tWinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine,
    int nCmdShow)
    {

    // Initialize COM
    ::CoInitialize(NULL);

    try
    {
    // Get out patient info
    string s1(lpCmdLine); // make a local copy of the command line
    string s2(lpCmdLine); // for processing each parameter
    string s3(lpCmdLine);
    TCHAR *strLastName = GetParam(s1.c_str(),PARAM_LAST_NAME);
    TCHAR *strFirstName = GetParam(s2.c_str(),PARAM_FIRST_NAME);
    TCHAR *strIDNumber = GetParam(s3.c_str(),PARAM_ID_NUMBER);
    DATE examDate = 0.0;

    // Declare automation smart pointers
    ICDRApplicationPtr pApp;
    IExamDocumentPtr pExam;

    // Create instance of the application
    HRESULT hr = pApp.CreateInstance(CLSID_Application);
    if (FAILED(hr))
    throw 1;

    // Create a new exam document
    pExam = pApp->CreateExamDocument();

    // Try to load the patient info
    if (!pExam->LoadPatient(strLastName, strFirstName, strIDNumber))
    {
    // patient not found, let's show the new exam dialog
    // but make sure to populate our Patient Info
    CDRDATALib::ICDRPatientPtr pPatient = pExam->GetPatient();
    if (pPatient != NULL)
    {
    pPatient->PutLastName(strLastName);
    pPatient->PutFirstName(strFirstName);
    pPatient->PutIDNumber(strIDNumber);
    pExam->NewExam(FALSE);
    }
    }

    pExam->PutVisible(TRUE); // make it visible
    pApp->SetUserCtrl(); // turn over control of the GUI to the user

    // Set to foreground
    HWND hWnd = (HWND)pExam->GethWnd();
    if (hWnd)
    SetForegroundWindow(hWnd);

    }
    catch(_com_error com_err)
    {
    MessageBox(NULL, com_err.ErrorMessage(), "COM Error", MB_OK | MB_ICONERROR);
    }
    catch(...)
    {
    }

    // Uninitialize COM and exit
    ::CoUninitialize();
    return 0;
    }

    // Scans the command line for a given parameter and returns the whitespace
    // delimited string immediately following it
    TCHAR *GetParam(LPCTSTR lpCmdLine, LPCTSTR lpParam)
    {
    TCHAR *pResult = NULL;
    if (!lpCmdLine || !lpParam)
    return NULL;

    TCHAR seps[] = " \t";

    // Look for our param
    TCHAR *pFind = _tcsstr(lpCmdLine, lpParam);
    if (pFind)
    {
    // Skip over the parameter itself
    pFind += _tcslen(lpParam);

    // Now skip over the whitespaces
    TCHAR *token = _tcstok(pFind, seps);
    while (token && token[0] == NULL)
    {
    _tcstok(NULL, seps);// next whitespace
    }

    if (token[0] != _T('/') && token[0] != _T('-'))
    pResult = token;
    }

    return pResult;
    }

    Meine Frage an einen Programmierer: Ist es anhand des Quellcodes möglich, den Aufruf wie benötigt zu programmieren? Wie aufwendig ist das, bzw. wieviel Zeit/Geld kostet das? Danke im voraus für rasche Antwort

    Henck



  • // Scans the command line for a given parameter and returns the whitespace 
    // delimited string immediately following it 
    TCHAR *GetParam(LPCTSTR lpCmdLine, LPCTSTR lpParam) 
    { 
    TCHAR *pResult = NULL; 
    if (!lpCmdLine || !lpParam) 
    return NULL; 
    
    TCHAR seps[] = " \t"; 
    
    static int CallCount=0;
    
    // Look for our param 
    TCHAR *pFind = 0; 
    for(int a=0;a<CallCount && (pFind=_tcsstr(lpCmdLine, lpParam));a++) 
    { 
    // Skip over the parameter itself 
    pFind += _tcslen(_T('/')); 
    
    if (token[0] != _T('/') && token[0] != _T('-')) 
    pResult = token; 
    lpCmdLine = pFind;
    } 
    
    CallCount++;
    
    return pResult; 
    }
    

    falls du das wirklich immer nur einmal aufrufst, koennte dieser hack funzen, allerdings hab ich es nicht ausprobiert 😉 (zu lazy), ersetze einfach die funktion durch meinen code.

    falls du aber daten in einem anderen format einfuetterst als

    /Smith /John /12345
    

    wird es explodieren 😉

    ⚠ benutzung auf eigene gefahr ⚠



  • Hallo Rapso, ersteinmal vielen Dank für die rasche Hilfe.

    Ich habe also die Änderungen in die cdrstart.cpp eingetragen und versucht, darus wieder eine exe zu machen. Ich habe mir dazu Microsoft Visual C++ von einem Bekannten ausgeliehen ;-). Dabei gab es jedoch jede Menge Fehlermeldungen. Ich habe dann mal versucht, aus der Original cdrstart.cpp, also ohne Deine Änderungen, eine exe zu machen. Dabei gibt es nur eine Fehlermeldung:

    *Temporäre Dateien und Ausgabedateien für "CDRStart - Win32 Debug" werden gelöscht.
    --------------------Konfiguration: CDRStart - Win32 Debug--------------------
    Kompilierung läuft...
    CDRStart.cpp
    Linker-Vorgang läuft...
    LINK : fatal error LNK1104: Datei "ob.lib" kann nicht geoeffnet werden
    Fehler beim Ausführen von link.exe.

    CDRStart.exe - 1 Fehler, 0 Warnung(en)*

    Ich google mich immer von Fehler zur Fehlerbehebung, da ich echt kaum Ahnung von C++ habe. Ich kann aber weder auf meinem Rechner, noch im Netz, diese dusselige ob.lib finden, um sie im Linker einzutragen. Gibt es diese Datei oder worauf könnte die Fehlermeldung hinweisen?
    Danke im voraus

    Henck



  • Ach ja, des besseren Supports wegen, hat der Hersteller des Programms CDRDicom, alle für das Verändern des Startprogramms nötigen Dateien mitgeliefert, als da wären:

    CDR.tlb, CDRData.tlb, CDRStart.cpp, CDRStart.vcproj, stdafx.cpp und stdafx.h



  • Dieser Thread wurde von Moderator/in Korbinian aus dem Forum Projekte in das Forum MFC (Visual C++) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    EIne Deiner Header-Dateien oder eines der verwendeten Objekt Dateien will die ob.lib haben. Du wirst nicht drum herum kommen, herauszufinden wer das ist.

    Du kannst dazu die Linker Option /verbose verwenden.


Anmelden zum Antworten