Thema: Quellcodelokalisierung und Quellcodeanalyse

- für das Seminar 'Projekt SW-Sanierung' im WS00/01 -

Autoren: Prof. Bothe, Uli Sacklowski
Datum: 28.11.00

Inhalt

1. Einordnung und Aufgabenstellung
2. Hinweise und Hilfestellungen
2.1 Installation der Trace-Tools und der aufgabenrelevanten Dateien
2.2 .ini-Datei und Dialogbox
2.3 Aus- und Eingabe der Dialogbox 'Allgemeine Einstellungen' und Hilfen zur Programmanalyse
2.4 Relevante WinAPI-Funktionen
2.5 Relevante Dateien

1. Einordnung und Aufgabenstellung

Trotz bekannter Funktionalitaet eines existierenden Systems besteht ein Grundproblem darin, den herausgearbeiteten Teilaufgaben (z. B. in unserem Fall: u. a. Manuelle Justage, Detektorsteuerung, Allgemeine Einstellungen) den ihnen entsprechenden Code zuzuordnen, um ihn analysieren zu koennen.

Ein Ansatz besteht in einer dynamischen Analyse des Systemverhaltens:
Ausgehend von bekannten Teilaufgaben werden Testfaelle festgelegt, die zu diesen Teilaufgaben gehoeren (z. B. in Form bestimmter Eingaben ueber das Nutzerinterface).

In Ermangelung fuer uns anwendbarer Tools wurden im Rahmen einer Studienarbeit einige sehr einfache Tools entwickelt. (Hier besteht vielleicht die Moeglichkeit, das Thema in weiteren Studien- bzw. Diplomarbeiten aufzugreifen). Diese Tools sind auf unseren Web-Seiten (VIII. Werkzeuge,   Trace-Tool - Nutzerdokumentation ) beschrieben, die auf ein ganz einfaches Teilproblem anzuwenden sind:

Fuer die Teilaufgabe 'Allgemeine Einstellungen' ist der zugehoerige Quellcode innerhalb des RTK-Systems zu ermitteln. Dabei koennen bereits die mit Hilfe von tracer.exe aufbereiteten RTK-Quellen (ausfuehrbares Exe-File: devel-tr.exe) verwendet werden.

Der mit den Tools 'herausgefilterte' Code und die in Pkt. 2.2 erwaehnten TMain-Methoden sollen anschliessend analysiert und bewertet werden. Dabei ist zu beachten, dass ein Teil des Codes der Behandlung der Nutzeroberflaeche, ein anderer Teil der inhaltlichen Bewaeltigung des Problems zuzuordnen ist.
Versuchen Sie, auf folgende Aspekte einzugehen:
- Inhaltliche Beschreibung der Codeteile
   (Aufgabe und Realisierungsstrategie einzelner Teile)
- Bewertung der aeusseren Form des Codes:
    Programierrichtlinien (Namenswahl, Layout, Kommentierung usw.),
    Programmstruktur (z. B. Umsetzung der OO?)

2. Hinweise und Hilfestellungen

2.1 Installation der Trace-Tools und des vorbereiteten RTK-Programmes

Zur Installation der Trace-Tools und des vorbereiteten RTK-Programmes finden Sie Hinweise auf unseren Web-Seiten:

VIII. Werkzeuge,   Trace-Tools - Anleitung zur Installation und zur Arbeit mit diesen
VIII. Werkzeuge,   Trace-Tools - Anleitung zur Traceanalyse eines vorbereiten RTK-Programmes

2.2 .ini-Datei und Dialogbox

Für diese Aufgabe benötigen Sie den  Steuerprogramm-Abschnitt aus der .ini-Datei und die Definition der Dialogbox 'Allgemeine Einstellungen'. Bei der Dialogbox sind die Bezeichnungen der Dialogbox und die der einzelnen Dialogfelder von Bedeutung.

.ini-Datei

Der Steuerprogramm-Abschnitt aus der Parameterdatei 'devel-tr.ini':

[Steuerprogramm]
Der Abschnitt beinhaltet allgemeine Angaben. Sie koennen fast alle ueber das  Fenster "Allgemeine Einstellungen" eingegeben werden.
User=Richter
     [char 80]
     Default: "Nutzer"
     repraesentiert durch "User"
     Name des Experimentators (Fenster: Allg. Einstellungen: Nutzer)
Target=SiBond
     [char 80]
     Default: "Probe"
     repraesentiert durch "Target"
     Name der gelieferten Probe. Steht auf der Probe.
     (Fenster: Allg. Einstellungen: Name)
Current=30
     [int]
     Einheit: Milliampere
     Default: 10
     repraesentiert durch "Current"
     Betriebsparameter "Strom" fuer die Roentgenquelle
     (Fenster: Allg. Einstellungen: Strom)
Voltage=40
     [int]
     Einheit: kV
     Default: 20
     repraesentiert durch "Voltage"
     Betriebsparameter "Spannung" fuer die Roentgenquelle
     (Fenster: Allg. Einstellungen: Hochspannung)
WaveLength=1.540
     [float]
     Einheit: Angstroem
     Default: 1.534
     repraesentiert durch "WaveLength"
     Betriebsparameter "Wellenlaenge" fuer die Roentgenquelle
     (Fenster: Allg. Einstellungen: Wellenlaenge)
Reflection=[224]
     [3 x +/-Ziffer ??]
     Default: 001
     repraesentiert durch "Reflection"
     Durch Gittervektoren bestimmte Messebene
     (Fenster: Allg. Einstellungen: Untersuchter Reflex)
Orientation=[001]
    [3 x +/-Ziffer ??]
     Default: 001
     repraesentiert durch "Orientation"
     Durch Gittervektoren bestimmte Orientierung der Probe
     (Fenster: Allg. Einstellungen: Orientierung)
Substrat=Si
     [char 80]
     Default: "Si"
     repraesentiert durch "TargetBulk"
     Substrat  der gelieferten Probe. Steht auf der Probe.
     (Fenster: Allg. Einstellungen: Substrat)
Comment=Topographie-Meßplatz
     [ char 160 ]
     Default: ""
     repraesentiert durch "Comment"
     Kommentar zum Experiment (Fenster: Allg. Einstellungen)

Dialogbox

Die Bezeichnungen der Dialogbox und die der einzelnen Dialogfelder sind im RC-File vereinbart.
Als Hilfestellung sind die ersten Bezeichner in dem anschließenden File kursiv dargestellt.

RC-File: MeasurementParam

MeasurementParam DIALOG 348, 240, 225, 129
STYLE DS_ABSALIGN | DS_MODALFRAME | DS_NOIDLEMSG | WS_POPUP | WS_CAPTION | WS_SYSMENU
CLASS "Bordlg"
CAPTION "Allgemeine Einstellungen"
FONT 10, "Times New Roman"
{
 CONTROL "GeSi188", id_TargetName, "EDIT", WS_BORDER | WS_TABSTOP, 177, 22, 37, 11
 EDITTEXT id_WaveLength, 63, 48, 31, 11, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
 CONTROL "Schmidbauer", id_Scientist, "EDIT", WS_BORDER | WS_TABSTOP, 64, 62, 48, 13
 EDITTEXT id_BeamCurrent, 63, 18, 24, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
 EDITTEXT id_BeamVoltage, 63, 32, 24, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
 EDITTEXT id_Text, 6, 91, 105, 25, ES_MULTILINE | WS_BORDER | WS_TABSTOP
 CONTROL "-1 -1 -4", id_Orientation, "EDIT", WS_BORDER | WS_TABSTOP, 177, 51, 30, 13
 PUSHBUTTON "&Beenden", IDOK, 124, 90, 50, 14, NOT WS_TABSTOP
 RTEXT "Name:", -1, 146, 23, 26, 10
 RTEXT "Wellenl?nge:", -1, 9, 49, 45, 10
 RTEXT "Nutzer:", -1, 10, 64, 45, 9
 LTEXT "Besondere Bedingungen:", -1, 8, 80, 85, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
 CONTROL "Betriebsparameter", -1, "BorShade", BSS_GROUP | BSS_CAPTION | BSS_CENTER | WS_CHILD | WS_VISIBLE, 3, 6, 112, 117
 RTEXT "Strom:", -1, 4, 20, 50, 9
 RTEXT "Hochspannung:", -1, 5, 30, 50, 9
 LTEXT "mA", -1, 95, 23, 16, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
 LTEXT "kV", -1, 95, 35, 16, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
 CONTROL "Angaben zur Probe", -1, "BorShade", BSS_GROUP | BSS_CAPTION | BSS_CENTER | WS_CHILD | WS_VISIBLE, 120, 6, 101, 77
 RTEXT "Orientierung:", -1, 125, 52, 47, 10
 CONTROL "-1 -1 -4", id_Reflection, "EDIT", WS_BORDER | WS_TABSTOP, 177, 66, 30, 13
 LTEXT "Untersuchter             Reflex :", -1, 127, 63, 45, 17
 CONTROL "Si", id_TargetBulk, "EDIT", WS_BORDER | WS_TABSTOP, 177, 36, 29, 13
 RTEXT "Substrat :", -1, 138, 37, 34, 10
 PUSHBUTTON "&Ok", IDOK, 181, 90, 34, 14
}

2.3 Aus- und Eingabe der Dialogbox 'Allgemeine Einstellungen' und Hilfen zur Programmanalyse

Durch zwei Vergleichsläufe, einmal mit und einmal ohne Aufruf der Dialogbox 'Allgemeine Einstellungen', ermitteln Sie die relevanten Methoden und Funktionen. Hilfreich bei der Analyse der Tracedateien sind die einzelnen Trace-Tools ( mehrfach, vergleich, ...). Für die Analyse genügt die Auswertung der .dev-Datei.

In unserem RTK-Programm werden fast alle Dialoge über eine allgemeine Template-Dialogklasse 'TModalDlg' realisiert. Dieser allgemeine Mechanismus geht jedoch auf Kosten eines schnellen Verständnisses. Deshalb betrachten Sie alle diese TModalDlg-Methoden (beginnend mit dem Konstruktor TModalDlg::TModalDlg und endend mit dem Destruktor TModalDlg::~TModalDlg) nicht weiter. Desgleichen betrachten Sie auch nicht die beiden Funktionen GetHKLund SetHKL.

Bei der weitergehenden Analyse treten einige Win-API-Funktionen auf. Zu zweien (GetDlgItemText und SetDlgItemText) ein paar Bemerkungen unter 2.3. Die übrigen brauchen Sie nicht weiter zu betrachten.

Des weiteren werden Sie feststellen, daß auf Variablen aus dem Objekt Main zugegriffen wird (z.B. Main.Target, Main.Voltage). Dieses Objekt wird schon in der Programm-Initialisierungsphase (also generell bei Programmstart) von der Klasse TMain abgeleitet und dabei wird auch der TMain-Konstruktor TMain::TMain abgearbeitet. Diesen schauen Sie sich bitte an. Hier aber nur den Teil ziemlich zu Anfang, der die WinAPI-Funktionen GetPrivateProfileString und GetPrivateProfileInt enthält, - Erläuterungen dazu unter 2.3. (Die Funktion SetHKL bitte wieder nicht anschauen). Hier werden die Werte aus dem [Steuerprogramm] - Abschnitt eingelesen.

Schließlich wird noch der TMain-Destruktor TMain::~TMain aufgerufen, der wiederum die Methode TMain::SaveProfile aufruft. Vorherrschend hier ist die WinAPI-Funktion SetPrivateProfileString, und damit erfolgt ein abschließendes Zurückschreiben der aktuellen Werte in den [Steuerprogramm] - Abschnitt.

Damit ergibt sich grob der Ablauf:

1. Einlesen der Werte aus dem [Steuerprogramm] - Abschnitt
2. Anzeigen der Werte in der Dialogbox 'Allgemeine Einstellungen'
3. Einlesen der (eventuell veränderten) Werte aus der Dialogbox 'Allgemeine Einstellungen'
4. Zurückschreiben der Werte in den [Steuerprogramm] - Abschnitt

2.4 Relevante WinAPI-Funktionen

The GetDlgItemText function retrieves the title or text associated with a control in a dialog box.

UINT GetDlgItemText(
    HWND hDlg, // handle of dialog box
    int nIDDlgItem, // identifier of control
    LPTSTR lpString, // address of buffer for text
    int nMaxCount  // maximum size of string
 );

Parameters

hDlg    Identifies the dialog box that contains the control.
nIDDlgItem    Specifies the identifier of the control whose title or text is to be retrieved.
lpString    Points to the buffer to receive the title or text.
nMaxCount    Specifies the maximum length, in characters, of the string to be copied to the buffer pointed to by lpString. If the length of the string exceeds the limit, the string is truncated.
 

The SetDlgItemText function sets the title or text of a control in a dialog box.

BOOL SetDlgItemText(
    HWND hDlg, // handle of dialog box
    int nIDDlgItem, // identifier of control
    LPCTSTR lpString  // text to set
 );

Parameters

hDlg   Identifies the dialog box that contains the control.
nIDDlgItem   Identifies the control with a title or text that is to be set.
lpString    Points to the null-terminated string that contains the text to be copied to the control.
 

The GetPrivateProfileString function retrieves a string from the specified section in an initialization file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

DWORD GetPrivateProfileString(
    LPCTSTR lpAppName, // points to section name        // bei uns vereinbart in m_main.cpp
    LPCTSTR lpKeyName, // points to key name
    LPCTSTR lpDefault, // points to default string
    LPTSTR lpReturnedString, // points to destination buffer
    DWORD nSize, // size of destination buffer                     // in unserem Fall: 80
    LPCTSTR lpFileName  // points to initialization filename         // in unserem Fall Pointer auf 'devel-tr.ini'
 );

Parameters
lpAppName     Points to a null-terminated string that specifies the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function copies all section names in the file to the supplied buffer.
lpKeyName     Pointer to the null-terminated string containing the key name whose associated string is to be retrieved. If this parameter is NULL, all key names in the section specified by the lpAppName parameter are copied to the buffer specified by the lpReturnedString parameter.
lpDefault     Pointer to a null-terminated default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer. This parameter cannot be NULL.
Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.
Windows 95: Although lpDefault is declared as a constant parameter, Windows 95 strips any trailing blanks by inserting a null character into the lpDefault string before copying it to the lpReturnedString buffer.
Windows NT: Windows NT does not modify the lpDefault string. This means that if the default string contains trailing blanks, the lpReturnedString and lpDefault strings will not match when compared using the lstrcmp function.
lpReturnedString     Pointer to the buffer that receives the retrieved string.
nSize     Specifies the size, in characters, of the buffer pointed to by the lpReturnedString parameter.
lpFileName     Pointer to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, Windows searches for the file in the Windows directory.
 

The GetPrivateProfileInt function retrieves an integer associated with a key in the specified section of the given initialization file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

UINT GetPrivateProfileInt(
    LPCTSTR lpAppName, // address of section name
    LPCTSTR lpKeyName, // address of key name
    INT nDefault, // return value if key name is not found
    LPCTSTR lpFileName  // address of initialization filename
 );

Parameters
Ähnlich GetPrivateProfileString
 

2.5 Relevante Dateien

m_main.cpp
m_dlg.h
m_dlg.cpp
comclass.h
comhead.h