AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Win32 non-Vcl ein zweites Window Modal und Umlaute Frage
Thema durchsuchen
Ansicht
Themen-Optionen

Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

Ein Thema von KodeZwerg · begonnen am 25. Mai 2018 · letzter Beitrag vom 26. Mai 2018
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 25. Mai 2018, 23:47
Zitat:
Es erstellt kein Modal Fenster
Wenn das dein einziges Problem ist?
Verhindere einfach dass das darunter liegende Fenster aktiv ist.

Also ein einfaches
EnableWindow(ParentWindow, false);

aber vergesse nicht es wieder einzuschalten wenn du das 2 Window schließt.

EnableWindow(ParentHandle, True);

bzw. Das Sample ist modal denn das zweite Fenster liegt über dem Parent und bleibt auch drüber.
Du musst halt nur dafür sorgen das dein Parent nicht aktiviert werden kann.
Zitat:
Vielen Dank an EWeiss für den "mit den Gesicht ins Ziel drücken" Link, das tat gut!!!
Na ja ist für mich einfacher als dir alles vorzukauen
Zumal da ich ganz andere Wege beschreite als das Luckie tut.

gruss

Geändert von EWeiss (26. Mai 2018 um 00:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 26. Mai 2018, 00:25
So hab ich es jetzt momentan, es macht genau das was ich wollte.
Vielen Dank nochmal!!

Ist DestroyWindow() das richtige Mittel um das Fenster zu schließen oder sollte da ein anderer Befehl hin?

Delphi-Quellcode:
{******************************************************************************}
{                                                                              }
{                                TwoWindows                                    }
{                                                                              }
{                    Copyright (c) 2001 Michael Puff                           }
{                            www.luckie-online.de                              }
{                           mpuff@luckie-online.de                             }
{                                                                              }
{******************************************************************************}
program TwoWindows;

{$R resource.res}

uses
  Windows,
  Messages;

const
  ClassName1 = 'Wnd1Class';
  ClassName2 = 'Wnd2Class';
  Window1Name = 'Window 1';
  Window2Name = 'Window 2';
  WindowWidth1 = 500;
  WindowHeight1 = 400;
  WindowWidth2 = 300;
  WindowHeight2 = 200;

  IDC_BUTTON1 = 1;

var
  hWnd1: DWORD;
  hWnd2: DWORD;

  hwndButton1: DWORD;

{Fensterfunktion für Fenster 1}
function Wnd1Proc(_hWnd1: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var
  x, y : integer;
begin
  Result := 0;
  case uMsg of
    WM_CREATE:
      begin
        {Fenster zentrieren}
        x := GetSystemMetrics(SM_CXSCREEN);
        y := GetSystemMetrics(SM_CYSCREEN);
        MoveWindow(_hWnd1, (x div 2) - (WindowWidth1 div 2),
          (y div 2) - (WindowHeight1 div 2),
          WindowWidth1, WindowHeight1, true);

        hwndButton1 := CreateWindowEx(0, 'BUTTON', 'Klick mich',
          WS_CHILD or WS_VISIBLE, 200, 160,
          100, 25, _hWnd1, IDC_BUTTON1, hInstance, nil);
      end;
    WM_COMMAND:
      begin
        if hiword(wParam) = BN_CLICKED then
          case loword(wParam) of
            IDC_BUTTON1:
              {Fenster 2 erzeugen und anzeigen}
              begin
                EnableWindow(_hWnd1, false);
                hwnd2 := CreateWindowEx(0, ClassName2, Window2Name,
                  WS_OVERLAPPEDWINDOW or WS_VISIBLE, 40, 10,
                  300, 200, _hWnd1, 0, hInstance, nil);
              end;
          end;
      end;
    WM_DESTROY:
      begin
        PostQuitMessage(0);
      end;
  else
    Result := DefWindowProc(_hWnd1, uMsg, wParam, lParam);
  end;
end;

{Fensterfunktion für Fenster 2}
function Wnd2Proc(_hWnd2: HWND; iMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var
  x, y : integer;
begin
  Result := 0;
  case iMsg of
    WM_CREATE:
      begin
        {Fenster zentrieren}
        x := GetSystemMetrics(SM_CXSCREEN);
        y := GetSystemMetrics(SM_CYSCREEN);
        MoveWindow(_hWnd2, (x div 2) - (WindowWidth2 div 2),
          (y div 2) - (WindowHeight2 div 2),
          WindowWidth2, WindowHeight2, true);
      end;
    WM_CLOSE:
      begin
        EnableWindow(hWnd1, True);
        DestroyWindow( _hWnd2 );
      end;
    else
      Result := DefWindowProc(_hWnd2, iMsg, wParam, lParam);
  end;
end;

{WindowStruktur für beide Fenster}
var
  wc: TWndClassEx = (
    cbSize : SizeOf(TWndClassEx);
    Style : CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc : @Wnd1Proc; //Fensterfunktion für Fenster 1
    cbClsExtra : 0;
    cbWndExtra : 0;
    hbrBackground : COLOR_APPWORKSPACE;
    lpszMenuName : nil;
    lpszClassName : ClassName1; //Klassenname für Fenster 1
    hIconSm : 0;
  );
  msg: TMsg;

begin
  {Struktur mit Infos für Fenster 1 füllen}
  wc.hInstance := hInstance;
  wc.hIcon := LoadIcon(hInstance,MAKEINTRESOURCE(100));
  wc.hCursor := LoadCursor(0, IDC_ARROW);

  {Fenster 1 registrieren}
  RegisterClassEx(wc);

  {Fenste 1 erzeugen und hWnd1 zuweisen}
  hWnd1 := CreateWindowEx(0, ClassName1, Window1Name, WS_VISIBLE or
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, WindowWidth1, WindowHeight1, 0, 0, hInstance,
    nil);

  {Struktur mit Infos für Fenster 2 füllen}
  wc.hInstance := hInstance;
  wc.lpfnWndProc := @Wnd2Proc; //Fensterfunktion für Fenster 2
  wc.hIcon := LoadIcon(0, IDI_INFORMATION);
  wc.hCursor := LoadCursor(0, IDC_ARROW);
  wc.lpszClassName := ClassName2; //Klassenname für Fenster 2

  {Fenster 2 registrieren}
  RegisterClassEx(wc);

  while GetMessage(msg,0,0,0) do
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;
  ExitCode := msg.wParam;
end.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 26. Mai 2018, 01:13
Zitat:
Ist DestroyWindow() das richtige Mittel um das Fenster zu schließen oder sollte da ein anderer Befehl hin?
Ist ok.. kommt halt auf das Fenster an das man erstellt
Bei Dialogen zum Beispiel würde ich EndDialog verwenden.
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Aber nicht verwechseln mit CreateDialogIndirectParam
dieser Dialog ist nicht MODAL deshalb musst du auch hier DestroyWindow verwenden.
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

Das hier
EnableWindow(_hWnd1, false);

besser hier hin.
in WM_CREATE der zweiten Winproc besser noch in der Funktion wo das neue Window erstellt wird.
anstelle das..
Delphi-Quellcode:
                EnableWindow(_hWnd1, false);
                 hwnd2 := CreateWindowEx(0, ClassName2, Window2Name,
                   WS_OVERLAPPEDWINDOW or WS_VISIBLE, 40, 10,
                   300, 200, _hWnd1, 0, hInstance, nil);
Delphi-Quellcode:
                 hwnd2 := CreateWindowEx(0, ClassName2, Window2Name,
                   WS_OVERLAPPEDWINDOW or WS_VISIBLE, 40, 10,
                   300, 200, _hWnd1, 0, hInstance, nil); // erste erstellen
                 EnableWindow(_hWnd1, false); // dann deaktivieren
erstelle zuerst das zweite Fenster dann deaktiviere das erste.
So wie du es machst könnte es zu einem Deadlock führen.. (Muss nicht, je nach dem was man im alten Fenster dann noch abarbeiten muss)

gruss

Geändert von EWeiss (26. Mai 2018 um 01:39 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 26. Mai 2018, 01:36
Bei Dialogen zum Beispiel würde ich EndDialog verwenden.
Hey, das ist ein toller Tipp wenn ich Dialoge aus Resource nutze, Danke!
in WM_CREATE der zweiten Winproc
erstelle zuerst das zweite Fenster dann deaktiviere das erste.
Jetzt wo Du es sagst, das ergibt mehr Sinn, Danke!


Damit ist für mich ein cooles Template entstanden für zwei Hobbyprojekte, bei einem weiß ich nicht ob ichs verteilen darf beim anderen handelt es sich um eine detailierte WhoIs Abfrage, das stelle ich bald vor da ich in DP irgendwie nur nicht funktionierende Programme dazu hier fand.

Vielen Dank an alle die sich die Zeit zum helfen nahmen!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 26. Mai 2018, 01:41
Zitat:
Jetzt wo Du es sagst, das ergibt mehr Sinn, Danke!
Habe es nochmal aktualisiert.
So ist es dann der letzte Vorgang im alten Fenster danach passiert ja nichts mehr und du hast alles abgearbeitet.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 26. Mai 2018, 02:21
So ist es dann der letzte Vorgang im alten Fenster danach passiert ja nichts mehr und du hast alles abgearbeitet.
Ich habe da so eine berühmte Vcl Weisheit im Kopf "ein deaktiviertes Fenster kann nicht den Fokus erhalten".
Von daher glaube ich schon das im WM_CREATE des zweiten Window das erste Window erst deaktiviert werden müsste oder irre ich mich da? Das war es als ich meinte das es Sinn ergibt, nun machst Du meine heile Welt kaputt *schmunzel*


Das ist jetzt mein momenter Template Hauptteil, muss nur noch Positionen der Buttons anpassen.
Delphi-Quellcode:
{Fensterfunktion für Fenster 1}
function Wnd1Proc(hWnd1: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var
  x, y : integer;
begin
  Result := 0;
  case uMsg of
    WM_CREATE:
      begin
        {Fenster zentrieren}
        x := GetSystemMetrics(SM_CXSCREEN);
        y := GetSystemMetrics(SM_CYSCREEN);
        MoveWindow(hWnd1, (x div 2) - (Window1Width div 2),
          (y div 2) - (Window1Height div 2),
          Window1Width, Window1Height, true);

        hwndBtnExit := CreateWindowEx(0, 'BUTTON', 'Beenden',
          WS_CHILD or WS_VISIBLE, 200, 300,
          100, 25, hWnd1, IDC_BTNEXIT, hInstance, nil);
        hwndBtnAbout := CreateWindowEx(0, 'BUTTON', 'Über',
          WS_CHILD or WS_VISIBLE, 200, 160,
          100, 25, hWnd1, IDC_BTNABOUT, hInstance, nil);
      end;
    WM_COMMAND:
      begin
        if HiWord(wParam) = BN_CLICKED then
          case LoWord(wParam) of
            IDC_BTNEXIT: SendMessage(hWnd1, WM_CLOSE, 0, 0);
            IDC_BTNABOUT:
              {Fenster 2 erzeugen und anzeigen}
              begin
                hWndAbout := CreateWindowEx(0, ClassName2, Window2Name,
                  WS_OVERLAPPEDWINDOW or WS_VISIBLE, 40, 10,
                  300, 200, hWnd1, 0, hInstance, nil);
              end;
          end;
      end;
    WM_DESTROY:
      begin
        PostQuitMessage(0);
      end;
  else
    Result := DefWindowProc(hWnd1, uMsg, wParam, lParam);
  end;
end;

{Fensterfunktion für Fenster 2}
function Wnd2Proc(hWnd2: HWND; iMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var
  x, y : integer;
begin
  Result := 0;
  case iMsg of
    WM_CREATE:
      begin
        EnableWindow(hWndMain, false);
        {Fenster zentrieren}
        x := GetSystemMetrics(SM_CXSCREEN);
        y := GetSystemMetrics(SM_CYSCREEN);
        MoveWindow(hWnd2, (x div 2) - (Window2Width div 2),
          (y div 2) - (Window2Height div 2),
          Window2Width, Window2Height, true);
        hwndBtnExit := CreateWindowEx(0, 'BUTTON', 'Beenden',
          WS_CHILD or WS_VISIBLE, 100, 100,
          100, 25, hWnd2, IDC_BTNEXIT, hInstance, nil);
      end;
    WM_COMMAND:
      begin
        if HiWord(wParam) = BN_CLICKED then
          case LoWord(wParam) of
            IDC_BTNEXIT: SendMessage(hWnd2, WM_CLOSE, 0, 0);
          end;
      end;
    WM_CLOSE:
      begin
        EnableWindow(hWndMain, True);
        DestroyWindow(hWnd2);
      end;
    else
      Result := DefWindowProc(hWnd2, iMsg, wParam, lParam);
  end;
end;
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Win32 non-Vcl ein zweites Window Modal und Umlaute Frage

  Alt 26. Mai 2018, 07:58
Zitat:
Ich habe da so eine berühmte Vcl Weisheit im Kopf "ein deaktiviertes Fenster kann nicht den Fokus erhalten".
Was hat das damit zu tun?
Und wo bekommt beim erstellen des neuen Fensters das alte den Focus wenn es sich erst danach selbst deaktiviert?
Es hat diesen bereits (Dein Button auf dem du klickst) und zwar solange bis das neue erstellt wird\wurde.

Du must das eigene Fenster aus der Funktion deaktivieren wo du das neue Window erstellst aber nicht vorher (vorher = Deadlock) je nach dem
was du danach noch tun willst und das Fenster es nicht kann weil deaktiviert

sondern nach dem erstellen und EnableWindow die letzte Aktion ist die im ButtonClick Event ausgeführt wird.
...
Ok mach wie du es willst.

EDIT:
Beispiel.

Du klickst auf Button und erstellst ein neues Fenster.
In dem Fenster das erstellt wird deaktivierst du das ParentWindow.
Jetzt möchte ich aber im ParentWindow was das neue Fenster erstellt noch etwas zeichnen nach dem das neue Fenster erstellt wurde.
Nun.. Was denkst du zeichnet sich dann noch nachdem du das Fenster von außerhalb deaktiviert hast? Klassischer Todesstoß

gruss

Geändert von EWeiss (26. Mai 2018 um 09:16 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:54 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