Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DialogBoxParam (https://www.delphipraxis.net/8615-dialogboxparam.html)

bayo 8. Sep 2003 22:13


DialogBoxParam
 
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

Luckie 8. Sep 2003 22:18

Re: DialogBoxParam
 
static hält die lokale Variable auch nach verlassen der Funktion im Speiche3r, so dass beim nächsten Aufruf der Funktion der Inhalt der Variable wieder zur Ferfügung steht. So etwas gibt es in Delphi nicht. Nimm eine globale Variable.

neolithos 9. Sep 2003 07:07

Re: DialogBoxParam
 
Du kannst dir aber mittels

SetProp
GetProp
RemoveProp

aushelfen...

Geschwindigkeit der Befehle ist heut eh kein Thema mehr.

Oder doch einen Globale Variable bzw. Variablen-Stack...


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz