Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » FAQ C / C++ (WinAPI, Konsole) » Standarddialoge

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 <
000
10.01.2003, 16:25 Uhr
void*
Generic Pointer
(Operator)


Erstellt von Uwe

Im API Teil 3 - Menüs, Icons haben wir ein Menü mit verschiedenen Auswahlmöglichkeiten erzeugt.

Die bei der Betätigung der Einträge Öffnen und Speichern sollte sich, wie in jeder Anwendung welche diese Möglichkeit bietet, der entsprechende Auswahldialog öffnen. Es gibt nun zwei Möglichkeiten zur Realisierung. Wir programmieren uns selbst einen solchen Dialog oder wir nutzen das was uns das Betriebssystem bietet. Für uns als 'Anfänger' nutzen wir hier die zweite Variante.
Diese Dialogbox gibt es seit Windows 3.1. Microsoft gab nach dem Erscheinen von Win 3.1 die für Standarddialog zuständige commdlg.dll

für die Entwicklung von Programmen frei. Die Prototypen der Dialog befindet sich in commdlg.h

Diesen Header müssen wir in unserer Anwendung aufnehmen. Wir nehmen uns unser Menü-Projekt vor.
Bis jetzt waren unsere Anwendungen eigentlich noch übersichtlich. Doch in Zukunft werden immer mehr Funktionen hinzukommen und der Überblick, was hab ich eigentlich wo definiert, geht bei größeren Anwendungen schnell verloren. Wir werden in Zukunft uns eine eigene Headerdatei anlegen, wo wir unsere Includes und eigene Prototypen von Funktionen definieren. Bei mir lautet der selbst vergebene Name der Headerdatei std.h. In dieser neu erzeugten Datei tragen wir nun unsere Includes ein.

C++:
// std.h

#include < windows.h >
#include < commdlg.h >
#include "resource.h"



Die in < > eingefassten Header sind vom Compiler bereits bereitgestellt Dateien und befinden sich in dessen Includeverzeichnis. Die in " " angegebenen Dateien sind von uns erstellte Header und befinden sich in unserem Entwicklungsverzeichnis.
In unserer *.c Datei geben wir nun unseren neuen Header bekannt

C++:
// dialog.c
// Unser neuer Header wird eingebunden
#include "std.h"

int WINAPI WinMain (HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        PSTR szCmdLine,
                        int iCmdShow)
{
   MSG msg;
...........
...........



Was wollen wir nun erreichen? "Datei/Öffnen" wird geklickt und der Dialog soll sich öffnen. Bevor das passiert haben wir noch ein paar Dinge zu erledigen.
Zunächst unsere Anwendung:

C++:
// std.h

#include < windows.h >
#include < commdlg.h >
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
#define FILTER "TextDatei (*.txt)\0*.txt\0HeaderDatei (*.h)\0*.h\0Alle Dateien(*.*)\0*.*\0\0"
static OPENFILENAME ofn = {0};

void Oeffnen();
void Speichern();

// dialog.c

#include "std.h"

int WINAPI WinMain (HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        PSTR szCmdLine,
                        int iCmdShow)
{
   MSG msg;

   WNDCLASSEX wc={0};

   wc.cbSize= sizeof (WNDCLASSEX);
   static char szAppName[]= "Standarddialoge";
   wc.style = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc = WndProc;
   wc.cbClsExtra = 0;
   wc.cbWndExtra = 0;
   wc.hInstance = hInstance;
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
   wc.lpszMenuName = "USERMENUE";
   wc.lpszClassName = szAppName;
   wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

   RegisterClassEx(&wc);

   HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,
                              szAppName,
                              "Standarddialog",
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);

    ShowWindow(hWnd, iCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, 0, 0)== TRUE)
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hwnd,
                          UINT message,
                          WPARAM wParam,
                          LPARAM lParam)

{
        HDC hdc;
        PAINTSTRUCT paintstruct;
                switch(message)
         {
          case WM_PAINT:
                  hdc = BeginPaint (hwnd, &paintstruct);

                  TextOut (hdc, 250, 200, "Der Dateiauswahldialog", 22);

                  EndPaint (hwnd, &paintstruct);
                  return 0;



          case WM_COMMAND:
               switch(LOWORD(wParam))
               {
                case ID_NEU:

                     MessageBox(NULL, "Button 'Neu' geklickt", "Menütest", MB_OK);
                     return 0;
                case ID_OEFFNEN:

                     Oeffnen();

                    return 0;
                case ID_SPEICHERN:

                     Speichern();

                     return 0;
                case ID_BEENDEN:
                     MessageBox(NULL,
                                "Button 'Beenden' geklickt - Programm wird beendet",
                                "Menütest",MB_OK);

                     SendMessage(hwnd, WM_CLOSE, 0, 0);
                     return 0;



                case ID_ITEM1:
                     SetWindowText(hwnd, "Diesen Text in die Titelleiste");
                     return 0;
                case ID_ITEM2:
                     SetWindowText(hwnd, "Und jetzt diesen Text");
                     return 0;
                case ID_ITEM3:
                     SetWindowText(hwnd, "");
                     return 0;
               }
               return 0;

               case WM_DESTROY:
                     PostQuitMessage(0);
               return 0;
         }
         return DefWindowProc (hwnd, message, wParam, lParam);
}

void Oeffnen()
{
        char DateiName[_MAX_PATH+1] = "";

        ofn.lStructSize       = sizeof (OPENFILENAME) ;
        ofn.hwndOwner         = NULL;
        ofn.nMaxFile          = _MAX_PATH;
        ofn.lpstrFile         = DateiName;
        ofn.lpstrFilter       = FILTER;
        if (GetOpenFileName(&ofn))
        {
                switch (ofn.nFilterIndex)
                {
                        case 1:
                             MessageBox(NULL, "Text Datei", "Öffnen", MB_OK);
                        break;
                        case 2:
                             MessageBox(NULL, "Header Datei", "Öffnen", MB_OK);
                        break;
                }
        }

}

void Speichern()
{
        char DateiName[_MAX_PATH+1] = "";

        ofn.lStructSize       = sizeof (OPENFILENAME) ;
        ofn.hwndOwner         = NULL;
        ofn.nMaxFile          = _MAX_PATH;
        ofn.lpstrFile         = DateiName;
        ofn.lpstrFilter       = FILTER;
        if (GetSaveFileName(&ofn))
        {
                switch (ofn.nFilterIndex)
                {
                        case 1:
                             MessageBox(NULL, "Text Datei", "Speichern", MB_OK);
                        break;
                        case 2:
                             MessageBox(NULL, "Header Datei", "Speichern", MB_OK);
                        break;
                }
        }

}


--
Gruß
void*
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.01.2003, 16:25 Uhr
void*
Generic Pointer
(Operator)


Die Funktion GetOpenFileName öffnet die Dialogbox zur Auswahl von Dateien, welche gelesen werden sollen. Der übergebene Parameter enthält die Struktur, welche die Dialogbox konfiguriert. Das für uns wichtigste Element der Strukur ist der Pointer lpstrFile, welcher den Speicherbereich nennt, in dem die ausgewählte Datei benannt wird.
Die Funktion GetSaveFileName dient der Auswahl einer Datei zum Sichern.
Die Funktion GetFileTitle trennt aus der angegebenen Datei den Dateinamen ohne Laufwerks- und Pfadnamen.

C++:
BOOL    WINAPI GetOpenFileName(OPENFILENAME FAR*);
BOOL    WINAPI GetSaveFileName(OPENFILENAME FAR*);
int     WINAPI GetFileTitle(LPCSTR, LPSTR, UINT);




Die Struktur von OPENFILENAME:

C++:
typedef struct tagOFN { // ofn
    DWORD         lStructSize;
    HWND          hwndOwner;
    HINSTANCE     hInstance;
    LPCTSTR       lpstrFilter;
    LPTSTR        lpstrCustomFilter;
    DWORD         nMaxCustFilter;
    DWORD         nFilterIndex;
    LPTSTR        lpstrFile;
    DWORD         nMaxFile;
    LPTSTR        lpstrFileTitle;
    DWORD         nMaxFileTitle;
    LPCTSTR       lpstrInitialDir;
    LPCTSTR       lpstrTitle;
    DWORD         Flags;

    WORD          nFileOffset;
    WORD          nFileExtension;
    LPCTSTR       lpstrDefExt;
    DWORD         lCustData;
    LPOFNHOOKPROC lpfnHook;
    LPCTSTR       lpTemplateName;
} OPENFILENAME;



Unsere Aufgabe besteht nun diese Struktur zu füllen. Als erstes wird in lStructSize die Größe der OPENFILENAME-Struktur entgegengenommen. Wir legen diese mit

C++:
sizeof(OPENFILENAME) fest. ofn.lStructSize       = sizeof (OPENFILENAME) ;  



Jetzt wird der Dateiname ermittelt und geliefert:

C++:
        char DateiName[_MAX_PATH+1] = "";

        ofn.lStructSize       = sizeof (OPENFILENAME) ;
        ofn.nMaxFile          = _MAX_PATH;
        ofn.lpstrFile         = DateiName;
        ofn.lpstrDefExt       = "txt";



lpstrFile zeigt hier auf eine Stringvariable, in unserem Fall auf DateiName, welche wir etwas weiter oben definiert und einen Leerstring zugewiesen haben. Die Zuweisung must vor dem Aufruf der Dialogbox erfolgen unsere Box würde sich sonst nicht öffnen. Die Länge unsers String wird in nMaxFile hinterlegt.
Soll die Datei z.B. ohne Angabe der Extension gespeichert werden wird mit dem Belegen von lpstrDefExt die Programmeigene Extension festgelegt. Also die Datei würde z.B. als "xyz.txt" gespeichert.
Mit LPCSTR lpstrFilter wird ein Filter zugewiesen. Der Filter dient dazu eine Liste der Dateimaske des Dialoges zu übergeben oder anders die unter Dateityp erscheinenden auswählbaren Dateien werden definiert.
Den Filter müssen wir selbst erzeugen:
#define FILTER "TextDatei (*.txt)\0*.txt\0HeaderDatei (*.h)\0*.h\0Alle Dateien(*.*)\0*.*\0\0"


Die Strings werden dabei direkt hintereinander geschrieben. Die Teilstrings sind durch eine binäre Null getrennt. Das Ende des Filters wird durch zwei Nullen gekennzeichnet.
Nach der Abarbeitung der Auswahlbox, ist in DWORD nFilterIndex der gewählte Filter enthalten. Der Index beginnt hier bei 1.
Durch DWORD Flags können Optionen, welche das Erscheinungsbild der Dialogbox beeinflussen, angegeben werden. Hier in ungeordneter Reihenfolge mögliche Flags.
OFN_ALLOWMULTISELECT


Erlaubt die Auswahl von mehreren Dateien. Im String für Dateinamen steht dann die Laufwerksbezeichnung und der Pfadname danach durch Leerzeichen getrennt die Liste der angewählten Dateinamen. OFN_PATHMUSTEXIST

Erzwingt, daß der User nur existierende Pfadnamen angeben kann. OFN_FILEMUSTEXIST

Erzwingt, daß der User nur existierende Dateinamen angeben kann. OFN_CREATEPROMPT

Signalisiert das die angegebene Datei nicht existiert und ermöglicht deren Erzeugung in einer Dialogbox. OFN_NOREADONLYRETURN

Erzwingt, daß die Datei nicht schreibgeschützt oder ein schreibgeschütztes Verzeichnis ist. OFN_READONLY

Erzwingt, daß der Schreibschutzknopf bei Start der Dialogbox angewählt ist. OFN_OVERWRITEPROMPT

Erzwingt bei einem "Speichen als..." Dialog, daß einer gleichnamigen Datei nachgefragt wird, ob überschrieben werden darf. OFN_HIDEREADONLY

Macht den Schreibschutzknopf unsichtbar.
#define OFN_NOCHANGEDIR 0x00000008

veranlaßt die Dialogbox , das aktuelle Verzeichnis dahin zurückzusetzen, wo die Dialogbox erzeugt wurde. OFN_SHOWHELP

Erzwingt einen Hilfebutton. hwndOwner darf dabei nicht NULL sein. OFN_NOVALIDATE

Erlaubt ungültige Zeichen im Dateinamen.

Die Werte können durch Addition untereinander kombiniert werden.

ofn.Flags = OFN_READONLY+OFN_SHOWHELP;


Der Aufruf des Öffnen- und Speicherndialoges wurde diesmal in separate Funktionen gesteckt, deren Prototypen im std.h erzeugt wurden.
Mit diesem Teil sind wir wieder ein Stück weiter gekommen. Es werden Beispiele folgen, wo wir, das was hier einzeln demonstriert wird, zu einer komplexeren Anwendung ausbauen werden. Noch sind wir dabei uns Grundlagen anzueignen,
--
Gruß
void*

Dieser Post wurde am 10.01.2003 um 16:26 Uhr von void* editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ FAQ C / C++ (WinAPI, Konsole) ]  


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: