AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Modale Dialogboxen blinken lassen

Ein Thema von mael · begonnen am 18. Apr 2005
Antwort Antwort
Benutzerbild von mael
mael

Registriert seit: 13. Jan 2005
391 Beiträge
 
Delphi XE3 Professional
 
#1

Modale Dialogboxen blinken lassen

  Alt 18. Apr 2005, 20:22
Euch ist vielleicht schon einmal aufgefallen, daß die Dialog-Boxen/Modale Fenster von Delphi-Anwendungen nicht "blitzen" (engl. flashing) wenn man auf darunterliegende Fenster klickt (was in normalen Windows-Anwendungen Standard ist). Außer einem Piep kommt nix.
Das hat mich lange genervt, also habe ich mich heute drangesetzt und habe eine Lösung gefunden.
Sogar ein Sonderfall der in Delphi 2005 (Demo) nicht ging geht hiermit in Delphi 7.

Es lies sich aber nicht vermeiden, daß Controls.pas entsprechend abgeändert werden muß.

Um den Bug zu fixen, in Controls.pas die Prozedur TWinControl.WMSetCursor durch den folgenden Code ersetzen:

Unter Windows 95 und NT 4.0 gibt es FlashWindowEx nicht, daher muß man es dynamisch laden. Dadurch haben sich ein paar Änderungen ergeben die leicht unübersichtlich erscheinen, weshalb ich eine diff-Datei angehängt habe.
Mit dem GNU-patch Tool kann man dann die Original-Datei im Source\VCL Ordner von Delphi 7 in die gefixte Version patchen. Dafür controls.diff aus Zip-Datei entpacken und das Kommando ausführen:
patch Controls.pas controls.diff

Delphi-Quellcode:
function FlashActivePopup(ClickedWindowHandle: HWND): Boolean;
var
  LastActivePopup: HWND;
  ClassName: array[0..255] of AnsiChar;
  IsDialog: Boolean;
begin
  // flash only on Windows 98+ or Windows 2000+
  if not (CheckWin32Version(4, 10) or CheckWin32Version(5, 0)) then
  begin
    Result := False;
    Exit;
  end;

  LastActivePopup := GetLastActivePopup(Application.Handle);

  GetClassName(LastActivePopup, @ClassName, 256);
  IsDialog := ClassName = '#32770';
  Result := IsDialog;
  
  // Windows already handles flashing if the parent is the clicked window
  Result := Result and (GetParent(LastActivePopup) <> ClickedWindowHandle);

  Result := Result or IsDelphiHandle(LastActivePopup) and
    (fsModal in TCustomForm(ObjectFromHWnd(LastActivePopup)).FormState);
end;

procedure TWinControl.WMSetCursor(var Message: TWMSetCursor);
var
  Cursor: TCursor;
  Control: TControl;
  P: TPoint;
  LastActivePopup: HWND;
  FlashInfo: FLASHWINFO;
begin
  with Message do
    if CursorWnd = FHandle then
      case Smallint(HitTest) of
        HTCLIENT:
          begin
            Cursor := Screen.Cursor;
            if Cursor = crDefault then
            begin
              GetCursorPos(P);
              Control := ControlAtPos(ScreenToClient(P), False);
              if (Control <> nil) then
                if csDesigning in Control.ComponentState then
                  Cursor := crArrow
                else
                  Cursor := Control.FCursor;
              if Cursor = crDefault then
                if csDesigning in ComponentState then
                  Cursor := crArrow
                else
                  Cursor := FCursor;
            end;
            if Cursor <> crDefault then
            begin
              Windows.SetCursor(Screen.Cursors[Cursor]);
              Result := 1;
              Exit;
            end;
          end;
        HTERROR:
          if (MouseMsg = WM_LBUTTONDOWN) and (Application.Handle <> 0) then
          begin
            LastActivePopup := GetLastActivePopup(Application.Handle);
            if (GetForegroundWindow <> LastActivePopup) then
            begin
              Application.BringToFront;
              Exit;
            end
            else if FlashActivePopup(Handle) then
            begin
              inherited; // make it beep
              
              FlashInfo.cbSize := sizeof(FlashInfo);
              FlashInfo.hwnd := LastActivePopup;
              FlashInfo.dwFlags := FLASHW_CAPTION;
              SystemParametersInfo(SPI_GETFOREGROUNDFLASHCOUNT, 0,
                @FlashInfo.uCount, 0);
              FlashInfo.dwTimeout := GetCaretBlinkTime div 8;
              FlashWindowEx(FlashInfo);

              Exit; // do not execute inherited again
            end;
          end;
      end;
  inherited;
end;
[edit=Chakotay1308]Beitrag angepasst. Mfg, Chakotay1308[/edit]
[edit=Chakotay1308]Anhang geupdatet. Mfg, Chakotay1308[/edit]
Angehängte Dateien
Dateityp: zip controls_610.zip (1,1 KB, 30x aufgerufen)
HxD, schneller Hexeditor:
http://mh-nexus.de/hxd
  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 19:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz