Thema: Delphi DialogBoxParam

Einzelnen Beitrag anzeigen

bayo

Registriert seit: 19. Aug 2003
Ort: ch
15 Beiträge
 
Delphi 5 Enterprise
 
#1

DialogBoxParam

  Alt 8. Sep 2003, 23:13
Hallo zusammen

Ich versuche gerade mit den api-funktionen einen Dialog zu erzeugen und.. grundsätzlich funktioniert das auch ganz gut wenn ich die funktion DialogBox verwende, muss ich, um daten zwüschen dem Dialog und dem Formular auszutauschen, globale variablen verwenden! So wie ich verstanden habe, kann man aber, um das zu vermeiden, die funktion DialogBoxParam verwenden und einen Zeiger z.b. auf einen Record mitgeben!? In meinem programm sie es wie folgt aus:

Delphi-Quellcode:
TTestRec = record
  Test: String;
end;

TfrmTest = class(TForm)
private
  FTestRec: TTestRec;
  procedure TestDlg;
end;

procedure TfrmTest.TestDlg;

  function DlgProc(hDlg: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
  begin
    Result := True;
    Case uMsg of
      WM_INITDIALOG: begin
        SetDlgItemText(hDlg, IDC_DICT_LOCATION, PChar(TTestRec(Pointer(lParam)^).Test));
      end;
      WM_COMMAND: begin
        case LOWORD(wParam) of
          ID_OK: EndDialog(hDlg, ID_OK);
          ID_CANCEL: EndDialog(hDlg, ID_CANCEL);
        end;
      end;
    else
      Result := False;
    end;
  end;

begin
  DialogBoxParam(hInstance, PChar('TESTDLG'), Handle, TFNDlgProc(@DlgProc), LPARAM(@FTestRec));
end;
Beim Starten des Dialogs wird der DialogProzedure die Nachricht WM_INITDIALOG geschickt und im lParam der Zeiger mitgegeben! Ich kann zu diesem Zeitpunkt sowohl in den record schreiben, wie auch von ihm lesen! Wenn der Benutzer seine eingaben gemacht hat und auf OK clickt sollte ich die Änderungen wieder in den record zurückschreiben können! dieser nachricht (WM_COMMAND) wird mein Zeiger natürlich nicht mehr mitgegeben ich müsste irgendwie die möglichkeit haben den zeiger bei der WM_INITDIALOG nachricht zu speichern, damit er mir nacher noch zur Verfügung steht!? Dazu möchte ich aber keine globalen veriablen verwenden! eine lokale veriable in der prozedur TestDlg finde ich auch nicht so gut und es funktioniert auch nicht (gibt eine accessviolation)!

folgend ein ausschnitt eines c-codes von dem buch "windows 2000 api referenz":

Code:
typedef struct
{
   int  nEditOne;
   char szEditTwo[20];
} DLGDATA, *LPDLGDATA;

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static LPDLGDATA lpMem;

   switch( uMsg )
   {
      case WM_CREATE :
              lpMem = (LPDLGDATA)HeapAlloc( GetProcessHeap(),
                                            HEAP_ZERO_MEMORY,
                                            sizeof( DLGDATA ) );
              lpMem->nEditOne = 10;
              strcpy( lpMem->szEditTwo, "Edit Two" );
              break;

      case WM_COMMAND :
              switch( LOWORD( wParam ) )
              {
                 case IDM_TEST :
                        DialogBoxParam( hInst, "TestDialog", hWnd,
                                        (DLGPROC)TestDlgProc,
                                        (LPARAM)lpMem );
                        break;
              }
              break;
     
      case WM_DESTROY :
              if ( lpMem )
                 HeapFree( GetProcessHeap(), 0, lpMem );

              PostQuitMessage(0);
              break;

      default :
            return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
   }

   return( 0L );
}


LRESULT CALLBACK TestDlgProc( HWND hDlg, UINT uMsg,
                              WPARAM wParam, LPARAM lParam )
{
static LPDLGDATA lpMem;

   switch( uMsg )
   {
      case WM_INITDIALOG :
            lpMem = (LPDLGDATA)lParam;

            SetDlgItemInt ( hDlg, IDC_EDIT1, lpMem->nEditOne, TRUE );
            SetDlgItemText( hDlg, IDC_EDIT2, lpMem->szEditTwo );
            break;

      case WM_COMMAND :
            switch( LOWORD( wParam ) )
            {
               case IDOK :
                      {
                         BOOL bTran;

                         lpMem->nEditOne = GetDlgItemInt( hDlg, IDC_EDIT1,
                                                   &bTran, TRUE );
                         GetDlgItemText( hDlg, IDC_EDIT2, lpMem->szEditTwo,
                                         sizeof(lpMem->szEditTwo)-1 );

                         EndDialog( hDlg, IDOK );
                      }
                      break;

               case IDCANCEL :
                      EndDialog( hDlg, IDCANCEL );
                      break;
            }
            break;

      default :
            return( FALSE );
   }

   return( TRUE );
}
Irgendwie kann man mit static z.b. dem code "static LPDLGDATA lpMem;" eine lokale variable erzeugen, die aber auch beim erneuten aufruf der procedure noch den zugewiesenen wert hat!? oder was passiert da so genau? gibt es in delphi evtl. auch so etwas ähndliches oder hat jemand eine andere idee, wie man diese funktion in delphi sinnvoll einsetzten kann? ich bedanke mich für jede antwort

Grüsse dominic
  Mit Zitat antworten Zitat