Announcement

Collapse
No announcement yet.

Windows-Dialoge erweitern und positionieren?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Windows-Dialoge erweitern und positionieren?

    Hallo,

    und gleich noch zwei Fragen:
    Ich möchte gerne dem eingebauten Windows-Printdialog ein paar Checkboxen (oder andere Eingabe-Komponenten) hinzufügen.
    Irgendwas habe ich da schon gemacht. Das funktioniert zwar, aber da reagiert die Maus nicht ganz sicher.

    Wie kann man das sicher machen?

    Kann man die Windows-Dialoge und -Anzeigen (auf möglichst gleiche Weise) auf dem Bildschirm positionieren?
    Für BrowseForFolder geht das ja. Aber z. Bsp. das Bild, das bei längeren Kopiervorgängen eingeblendte wir. Das hätte ich auch ganz gerne in der Mitte. Wie geht das? Aber, wie gesagt, auch die anderen Dialoge???

    Gruß aus Bärlin
    Matthias

  • #2
    Hallo,

    bei den Common Dialogs hat Microsoft die Option der <b>Templates</b> vorgesehen, um eigene Umgestaltungen/Erweiterungen an den Dialogen vornehmen zu können. Am Beispiel von <b>GetOpenFileName</b> sieht das zum Beispiel so aus: <br>
    1. OPENFILENAME-Struktur: Flag OFN_ENABLETEMPLATE setzen <br>
    2. Resource Workshop: COMDLG32.DLL öffnen und Dialog-Ressource <b>1536</b> als Vorlage öffnen, bearbeiten und in die eigenen RES-Datei kopieren<br>
    3. OPENFILENAME-Struktur: lpTemplateName mit dem Resourcenamen belegen <br>
    4. "Datei öffnen"-Dialog über die API-Funktion GetOpenFileName öffnen und die OPENFILENAME-Struktur als Parameter übergeben.

    Was die Positionierung angeht, würde ich mit dem Delphi-Tool <b>WinSight32</b> den Klassennamen des gesuchten Fensters ermitteln und dann über <b>FindWindow</b> und <b>SetWindowPos</b> das Teil an den gewünschten Platz verschieben.
    &#10

    Comment


    • #3
      Hallo Andreas,

      vielen Dank für den Tipp mit den Templates.
      Es ist schon ein Kreuz mit diesem Windows und Delphi! Sobald man es etwas hübscher machen will, muss man sehr viel Eigenleistung reinstecken.
      Irgendwann ist mir sogar mal aufgefallen, dass es Dialog-Ressourcen für die Standarddialoge geben müsste. Als ich mir aber klar darüber wurde, was ich da alles zu durchsuchen habe, habe ich es schnell wieder vergessen. <g>

      Ich werd' das dann mal probieren. Ich freu' mich schon... Aber zuerst suche ich mal etwas zur Arbeit mit templates. Hast Du da vielleicht auch einen Tipp?

      Gruß
      Matthia

      Comment


      • #4
        Hallo,

        das letzte Projekt - bei dem ich so etwas gemacht habe - betraf einen TrueType-Schriftmanager, der 1994 mit <b>Borland Pascal 7.0</b> für Windows 3.1 geschrieben wurde. Der Aufruf des erweiterten Schriftarten-Dialogs füge ich als Auszug bei - aber das waren wohlgemerkt noch die "schlechten" alten 16-Bit-Zeiten. Die Vorgehensweise sollte aber heute nicht anders sein:
        <pre>
        (* Antwortmethode auf den Button "Test" :
        Z.Zt. zur Verfügung stehende TrueType-Schriften in einem
        Dialogfenster anzeigen. Der im Resource Workshop erstellte
        Dialog "FontDlg" ist eine bearbeitete Variante des Standard-
        Dialogs aus COMMDLG - die nicht benötigten Steuerelemente
        wurden im Resource Workshop aus dem Dialogfenster gezogen
        und sind damit unsichtbar. Die übrigen Steuerlemente wurden
        neu plaziert. *)

        PROCEDURE TManWin.IDTest;
        BEGIN
        { Text für die Statuszeile aus den Ressourcen laden }
        SetInfoText(id_Test);

        (* TLogFont-Struktur vorbesetzen - definiert Standardt-
        Schriftart und Größe für das ChooseFont-Dialogfenster *)

        FillChar(LF, SizeOf(LF), #0);
        WITH LF DO BEGIN
        lfHeight:= 40;
        lfWidth := 0;
        lfWeight:= 400;
        StrCopy(lfFaceName, 'Arial')
        END;
        { TChooseFont-Struktur initialisieren }
        FillChar(CF, SizeOf(TChooseFont), #0);
        WITH CF DO BEGIN
        lStructSize := SizeOf(tChooseFont);
        hInstance := hInstance;
        nFontType := SCREEN_FONTTYPE;
        Flags := CF_TTOnly OR CF_ScreenFonts OR
        CF_InitToLogFontStruct OR
        CF_EnableTemplate;
        hWndOwner := hWindow;
        lpLogFont := @LF;
        (* Standard-Dialogfenster aus CommDlg durch den eigenen
        Dialog ersetzen *)
        lpTemplateName := 'FontDlg';
        rgbColors := GetSysColor(Color_WindowText);
        CF.hInstance := System.hInstance
        END;
        ChooseFont(CF);
        pStatus^.SetText(szStartDir)
        END;
        </pre>
        P.S: Selbstverständlich dürfen die vorhandenen Controls nur verschoben/versteckt, aber nicht gelöscht werden. Auch die IDs müssen ungeändert bleiben. Allerding darf man eigene Controls hinzufügen

        Comment


        • #5
          Hallo Andreas,

          in TCommonDialog ist ja sogar die Eigenschaft Template definiert - allerdings protected. Und leider wird sie auch nur bei OpenDialog und SaveDialog genutzt. Und ich will den PrintDialog...
          Aber kein Problem! Ein kleiner Ableger und es geht.
          Ich habe es bisher geschafft, mich um Resourcen zu drücken - Asche auf mein Haupt. Deshalb habe ich noch ziemliche Probleme. Irgendwie fehlt mir da noch die Verbindung zwischen dem neu eingefügten Control und wie man das aus dem Programm heraus (über seine ID) anspricht. (Außerdem bin ich bequem und möchte das möglichst direkt in der Execute-Methode machen.)
          Nun, ich habe Zeit zum Puzzeln. Ich werde es schon finden.

          Auf jeden Fall vielen Dank für die Tipps. Damit habe ich die Spur gefunden.

          Gruß aus Bärlin
          Matthia

          Comment


          • #6
            Hallo,

            um die eigenen, zusätzlich eingefügten Controls auswerten zu können, muss das Strukturfeld <b>lpfnHook</b> (um bei meinem ober verwendeten Beispiel zu bleiben) mit der eigenen Hook-Funktion initialisiert werden. Allerdings reagiert Win32 erst dann, wenn auch das Flag <b>CF_ENABLEHOOK</b> gesetzt wird. Diese Hook-Funktion ist nichts anderes als eine Fensterprozedur, die für das Auswerten der Botschaften dieses Dialogs zuständig ist.

            An dieser Stelle ist man so nah an Win32 (klassische API-Programmierung), dass ich auf TOpenDialog verzichten würde. Statt dessen würde ich eine eigene Funktion in einer Unit implementieren. Das folgende Beispiel stellt die neuen Fähigkeiten von Windows 2000 mit seiner neuen <i>Speichern unter</i>-Dialogvariante zur Verfügung:
            <pre>
            function OSDlgSave(var sSaveFile: String): Bool;
            var
            aOFN : TOpenFileNameW2K; // aus SDK übernommen
            TempFilter,
            TempFilename : String;
            begin
            Result := False;
            FillChar(aOFN, SizeOf(aOFN), 0);
            with aOFN do
            begin
            lStructSize := SizeOf(TOpenFileNameW2K);
            hInstance := SysInit.HInstance;
            nFilterIndex := 0;
            nMaxFile := MAX_PATH;
            SetLength(TempFilename, nMaxFile + 2);
            lpstrFile := PChar(TempFilename);
            FillChar(lpstrFile^, nMaxFile + 2, 0);
            Flags := OFN_EXPLORER;
            lpfnHook := nil;
            lpTemplateName := nil;
            hWndOwner := Application.Handle;
            end;
            Result := GetSaveFileName(aOFN);
            sSaveFile := aOFN.lpstrFile;
            end;
            </pre&gt

            Comment


            • #7
              Hallo Andreas,

              vielen Dank! Da habe ich wohl den Wald vor lauter Bäumen nicht gesehen! Genau die Zuweisung des eigenen Hooks für den Dialog habe ich nämlich gesucht und nicht gefunden. Ich habe sowas in anderer Beziehung mal gemacht und gedacht, dass es doch hier genauso sein müsste. Aber, wie gesagt, bisher hatte ich offenbar Tomaten auf den Augen!

              Gruß aus Bärlin
              Matthia

              Comment


              • #8
                Hallo Andreas,

                nur noch eine Frage zu den Templates:
                Im Res-Workshop (4.5) kann man für ein Control auch die Eigenschaft visible festlegen. Ich dächte, dass man das nun auch zur Laufzeit (im Hook) machen kann, aber ich finde einfach keine mögliche (API-)Funktion. Kannst Du mir einen Tipp geben oder kann man das denn nicht zur Laufzeit ändern?

                Ansonsten funktioniert alles prächtig. Der Res-WorkShop will zwar nichts aus der Comdlg32.dll kopieren (Incomplete expression), aber das kann man mit "add to project..." umgehen.

                Gruß aus Bärlin
                Matthia

                Comment


                • #9
                  Hallo,

                  der Aufruf von ShowWindow mit dem Wert <b>SW_HIDE</b> sollte die störenden Controls auch zur Laufzeit ausblenden

                  Comment


                  • #10
                    Hallo Andreas,

                    vielen Dank. Ich dachte mir das zwar schon, aber ich habe die Funktion, mit der man das Handle eines Controls aus dem Button-Control Identifier eines Dialog-Box-Templates bekommt, nicht gefunden. Nach Deiner Bestätigung habe ich nun nochmals gesucht und da fiel sie mir (fast) sofort in die Augen.
                    Nun habe ich dank Deiner Hilfe die Dialog-Templates geschafft. Uff!

                    Also, vielen Dank nochmals!

                    Gruß aus Bärlin
                    Matthia

                    Comment

                    Working...
                    X