Dialoge - Ordnerauswahl mit Zusatzfunktion



  • Hey kann mir einer sagen wie ich bei dem SelectDirectory() Dialog einen zusätzlichen Button mit "neuer Ordner" bekomme. Das hab ich nämlich schon gesehen. Damit mein ich das gleiche Dialog Fenster wie bei SelectDirectory(), nur das unten nicht nur "OK" und "Abrechen" steht sondern auch noch ein Button mit "neuer Ordner".

    [ Dieser Beitrag wurde am 25.06.2003 um 15:00 Uhr von Jansen editiert. ]



  • hm... wenn du SHBrowseForFolder nehmen würdest, könnte ich dir das zeigen...

    ansonsten einfach mit CreateWindow einen neuen button erstellen und diesem dem handle des dialoges zuweisen. dann noch mit SetWindowLong eine ereignis-behandlung für OnClick erstellen und fertig...

    [ Dieser Beitrag wurde am 30.04.2003 um 17:31 Uhr von Sunday editiert. ]



  • Kannst du mir das mit CreateWindow und SetWindowLong genauer erklären, wie das funktioniert?



  • Original erstellt von Sunday:
    hm... wenn du SHBrowseForFolder nehmen würdest, könnte ich dir das zeigen...

    Hmmm [Semi-OT]Daran wär ich jetzt sehr interessiert... da könnt ich viel Freude in der Firma stiften, würde ich so ein button einbauen (o: Bitte bitte bitte (o:[/Semi-OT]

    -junix



  • okay hier kommt der code. ich habe bei mir den button eingfügt um über diesen ein weiteres formular zu öffnen, in dem man den neuen pfad eingeben kann (formular: 1 TEdit, 2 TButton (Okay, Abbruch)). ich habe das bei mir in keiner klasse drin, sondern nur in eine externen unit stehen. ist alles auf meine bedürfnisse zugeschnitten... anpassungen muss jeder selber durchführen... 😉

    im header:

    // forward-deklarationen
    AnsiString SelectFolderDialog(HWND handle, AnsiString titel, AnsiString pfad, bool flag);
    LRESULT CALLBACK OwnWndProc(HWND handle, UINT Msg, WPARAM wParam, LPARAM lParam);
    void AddNewButton(HWND handle);
    
    // speicher freigeben
    template <class T> void SafeRelease(T &item) 
    { 
      if (item) 
      {
        delete item; 
        item = NULL;  
      }
    }
    

    im cpp:

    TF_DirCreate *form;         // variable für das neue formular
    const int     CM_NEW = 100; // unique-id
    HWND          new_button;   // handle des button
    
    /* SELECTFOLDERDIALOG */
    
    // on-click-funktion des new-buttons
    LRESULT CALLBACK OwnWndProc(HWND handle, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
      if ((Msg == WM_COMMAND) && (wParam == CM_NEW))
      {
        // wenn formular angezeigt wurde und mit okay bestätigt wurde
        // dann die message an den button weiterleiten
        if (form->ShowModal() == mrOk)
          PostMessage(handle, Msg, ID_OK, 0);
    
        return 1;
      }
      else
        // standard verarbeitung
        return DefDlgProc(handle, Msg, wParam, lParam);
    }
    
    // new-button in SHBrowseForFolder-Dialog zeichnen
    void AddNewButton(HWND handle)
    {
      HWND tmp_handle;
      int x1, y1, h1;     // eigenschaften des buttons (left, top, height)
      TRect rect;         // koordinaten des okay-buttons
      TPoint point;
    
      tmp_handle = GetDlgItem(handle, ID_OK); //ok-button
      GetWindowRect(tmp_handle, &rect);
    
      point.x = rect.left;
      point.y = rect.top;
    
      ScreenToClient(handle, &point);
    
      x1 = point.x - 90;  // 75 (breite) + 15 (abstand)
      y1 = point.y;
      h1 = rect.bottom - rect.top;
    
      // einen neuen button erzeugen (eigenschaften in der hilfe nachlesbar)
      new_button = CreateWindow("BUTTON", "Neu", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE |
                                WS_TABSTOP | BS_PUSHBUTTON, x1, y1, 75, h1, handle, (HMENU) CM_NEW,
                                HInstance, NULL);
    
      // font des okay-buttons im neuen button setzen (text in der std-sprache)
      PostMessage(new_button, WM_SETFONT, SendMessage(tmp_handle, WM_GETFONT, 0, 0),
                  MAKELPARAM(LANG_NEUTRAL, SUBLANG_DEFAULT));
    
      // standard-mässig ist new-button deaktiviert
      EnableWindow(new_button, false);
    
      // new-button eine eigene ereignis-prozedur zuweisen
      SetWindowLong(handle, GWL_WNDPROC, (LONG) OwnWndProc);
    }
    
    // Callback-Funktion für SelectFolderDialog zum Ändern des
    // vorausgewählten Verzeichnisses und anderem Krimskrams
    int __stdcall FolderCallback(HWND DlgHandle, UINT Msg, LPARAM lParam, LPARAM lpData)
    {
      switch(Msg)
      {
        // beim initialisieren
        case BFFM_INITIALIZED :
        {
          // new-button zeichnen
          if (form != 0)
            AddNewButton(DlgHandle);
    
          // start-verzeichnis setzen
          SendMessage(DlgHandle, BFFM_SETSELECTION, (LPARAM) true, lpData);
    
          // beschriftung des okay-buttons ändern (OK -> Okay)
          SetWindowText(GetDlgItem(DlgHandle, ID_OK), "Okay");
    
          break;
        }
    
        // beim wechsel des verzeichnisses
        case BFFM_SELCHANGED :
        {
          if (form != 0)
          {
            // new-button nur aktivieren, wenn okay-button aktiv ist
            EnableWindow(new_button, IsWindowEnabled(GetDlgItem(DlgHandle, ID_OK)));
    
            char szDir[MAX_PATH];
            SHGetPathFromIDList((LPCITEMIDLIST) lParam, szDir);
    
            // gewählten pfad in extra-formular vermerken (wird dort beim anzeigen 
            // im TEdit eingetragen)
            form->tmp_pfad = AnsiString(szDir);
          }
    
          break;
        }
      }
    
      return 0;
    }
    
    // Windows-Verzeichnisauswahl-Dialog anzeigen
    //  handle -> HANDLE des aufrufenden Formulares
    //  titel  -> Titel des Dialoges (Caption)
    //  pfad   -> wenn leerstring ("") dann wird die Callback-Funktion
    //            nicht aufgerufen und das Root-Verzeichnis als Ausgang gewählt
    //  flag   -> steuert anzeige des New-Buttons
    AnsiString SelectFolderDialog(HWND handle, AnsiString titel, AnsiString pfad, bool flag)
    {
      BROWSEINFO    info;
      char          szDir[MAX_PATH];
      char          szDisplayName[MAX_PATH];
      LPITEMIDLIST  pidl;
      LPMALLOC      pShellMalloc;
    
      form = 0;
    
      // soll extra-formular angezeigt werden, dann formular erstellen
      if (flag)
        form = new TF_DirCreate(Application);
    
      if (SHGetMalloc(&pShellMalloc) == NO_ERROR)
      {
        memset(&info, 0x00, sizeof(info));
    
        info.hwndOwner      = handle;
        info.pidlRoot       = 0;
        info.pszDisplayName = szDisplayName;
        info.lpszTitle      = titel.c_str();
        info.ulFlags        = BIF_RETURNONLYFSDIRS;
    
        // callback nur benutzen, wenn startpfad angegeben wurde
        if (!pfad.IsEmpty())
        {
          info.lParam       = (int) pfad.c_str();
          info.lpfn         = FolderCallback;
        }
        else
          info.lpfn         = 0;
    
        pidl = SHBrowseForFolder(&info);
    
        // Id in Pfad umwandeln
        if (pidl)
          SHGetPathFromIDList(pidl, szDir);
    
        // aufräumen
        pShellMalloc->Free(pidl);
        pShellMalloc->Release();
    
        // formular wenn benutzt freigeben
        if (!pidl)
        {
          SafeRelease(form);
          return "";
        }
      }
      else
      {
        SafeRelease(form);
        return "";
      }
    
      AnsiString new_dir = "";
    
      // wenn button angezeigt wurde, dann den inhalt des Edit in einer Variablen
      // vermerken
      if (flag)
      {
        new_dir = form->Edit2->Text;
        SafeRelease(form);
      }
    
      // gewählten pfad zurückgeben
      if (Trim(new_dir) != "")
      {
        AnsiString dir = AnsiString(szDir);
    
        if (dir[dir.Length()] == '\\')
          dir.Delete(dir.Length(), 1);
    
        return dir + "\\" + Trim(new_dir);
      }
      else
        return AnsiString(szDir);
    }
    

    aufruf-beispiele:

    AnsiString folder = SelectFolderDialog(F_Optionen->Handle, 
                                           "Sicherungsverzeichnis wählen", 
                                           "c:\\blahblah", 
                                           true);
    
    AnsiString folder = SelectFolderDialog(F_MandantExport->Handle,
                                           "Startverzeichnis wählen",
                                           "", 
                                           false);
    

    anmerkung:

    ihr könnt ja mal mit folgenden flags spielen für info.ulFlags = BIF_RETURNONLYFSDIRS;:

    BIF_EDITBOX 
    BIF_NEWDIALOGSTYLE;
    


  • Meine Frage wie ich es mit SelectDirectory() machen kann ist damit aber nicht beantwortet. Kann mir niemand weiter helfen?



  • Original erstellt von Mike8:
    kann mir einer sagen wie ich bei dem SelectDirectory() Dialog einen zusätzlichen Button mit "neuer Ordner" bekomme.

    Wenn du es unbedingt explizit hören willst: gar nicht.

    SelectDirectory ist nur ein dünner SHBrowseForFolder-Wrapper, eben ohne die zusätzliche Funktionalität.


Anmelden zum Antworten