Legacy GM [SOLVED] get_directory(dname)

Discussion in 'Advanced Programming Discussion' started by Samuel Venable, Mar 14, 2018.

  1. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,265
    Older versions of GameMaker, i.e., v4.3 to v8.1 had this function:

    get_directory.png

    get_directory(dname)

    Anyone know what C++ function or API was used to make this dialog box?
    Or was it custom-made specifically for GameMaker?

    I am trying to make an extension that brings this function back.
    I can't seem to find it used anywhere but in GameMaker.

    My extension currently supports:
    • get_open_filename(filter, fname)
    • get_save_filename(filter, fname)
    • get_open_filename_ext(filter, fname, dir, title)
    • get_save_filename_ext(filter, fname, dir, title)
    • get_directory_alt(capt, root)
    get_directory(dname) is the only thing that needs implementation before I'm ready to publish this extension to the marketplace for GameMaker Studio 1.4 and 2. Any chance some YoYo staff would be generous enough to explain how they made get_directory()?

    Thanks!
    Samuel
     
    Last edited: Mar 14, 2018
  2. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,405
    Based on slightly misaligned box I would guess that it was a custom dialog.

    A similar without making dialogs would probably be (mostly borrowed from here)
    Code:
    #include <Windows.h>
    #include <ShlObj.h>
    //
    int BrowseForFolder(HWND hwnd, LPCWSTR strTitle, bool bEdit) {
        BROWSEINFO bi;
        TCHAR Buffer[MAX_PATH];
        ZeroMemory(Buffer, MAX_PATH);
        ZeroMemory(&bi, sizeof(bi));
        bi.hwndOwner = hwnd;
        bi.pszDisplayName = Buffer;
        bi.lpszTitle = strTitle;
        bi.ulFlags = BIF_USENEWUI | BIF_BROWSEINCLUDEFILES | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE;
        LPCITEMIDLIST pFolder = SHBrowseForFolder(&bi);
        if (pFolder == NULL) return -1;
        if (!SHGetPathFromIDList(pFolder, Buffer)) return -2;
        // <do something with Buffer>
        printf("%ls\n", Buffer);
        return 0;
    }
    I've seen a GetOpenFilename style dialog for picking a directory in various software, perhaps done via something in common library?

    Edit: or this answer for Vista and above.
     
    Last edited: Mar 14, 2018
    Samuel Venable likes this.
  3. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,265
    @YellowAfterlife

    Yeah, that is what get_directory_alt() uses, which I already have implemented. If you are interested in seeing what I have, here's the file:
    Code:
    #include "stdafx.h"
    #include <windows.h>
    #include <Commdlg.h>
    #include <Shlobj.h>
    #include <wchar.h>
    #include <algorithm>
    #include <string>
    #include <vector>
    
    #define DLL extern "C" _declspec(dllexport)
    using namespace std;
    
    typedef basic_string<WCHAR> tstring;
    tstring widen(string str)
    {
        const size_t wchar_count = str.size() + 1;
        vector<WCHAR> buf(wchar_count);
        return tstring{ buf.data(), (size_t)MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buf.data(), wchar_count) };
    }
    
    string shorten(tstring str)
    {
        int nbytes = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length(), NULL, 0, NULL, NULL);
        vector<char> buf((size_t)nbytes);
        return string{ buf.data(), (size_t)WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length(), buf.data(), nbytes, NULL, NULL) };
    }
    
    DLL char *get_open_filename(char *filter, char *fname)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = NULL;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
    
        if (GetOpenFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_save_filename(char *filter, char *fname)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = NULL;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_OVERWRITEPROMPT;
    
        if (GetSaveFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_open_filename_ext(char *filter, char *fname, char *dir, char *title)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
        string str_dir = dir;
        string str_title = title;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
        tstring tstr_dir = widen(str_dir);
        tstring tstr_title = widen(str_title);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = tstr_title.c_str();
        ofn.lpstrInitialDir = tstr_dir.c_str();
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
    
        if (GetOpenFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_save_filename_ext(char *filter, char *fname, char *dir, char *title)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
        string str_dir = dir;
        string str_title = title;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
        tstring tstr_dir = widen(str_dir);
        tstring tstr_title = widen(str_title);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = tstr_title.c_str();
        ofn.lpstrInitialDir = tstr_dir.c_str();
        ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_OVERWRITEPROMPT;
    
        if (GetSaveFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_directory_alt(char *capt, char *root)
    {
        BROWSEINFOW bi;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_capt = capt;
        string str_root = root;
        tstring tstr_capt = widen(str_capt);
        tstring tstr_root = widen(str_root);
        WCHAR wstr_dir[MAX_PATH];
    
        LPITEMIDLIST pstr_root;
        SHParseDisplayName(tstr_root.c_str(), 0, &pstr_root, 0, 0);
    
        ZeroMemory(&bi, sizeof(bi));
        bi.hwndOwner = SitehWnd;
        bi.pidlRoot = pstr_root;
        bi.pszDisplayName = wstr_dir;
        bi.lpszTitle = tstr_capt.c_str();
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON;
    
        LPITEMIDLIST lpItem = SHBrowseForFolderW(&bi);
        if (lpItem != NULL)
        {
            if (SHGetPathFromIDListW(lpItem, wstr_dir) == 0)
                return (char *)"";
            else
            {
                static string result;
                result = shorten(wstr_dir);
                return (char *)result.c_str();
            }
        }
    
        return (char *)"";
    }
    I think I'm going to make my own dialog then, worst case scenario, and make it look as close as to what legacy GM used as possible. :)
     
    Last edited: Mar 14, 2018
  4. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,265
    I managed to manipulate the old-style GetOpenFileName() to look almost exactly like GM 8.1's get_directory() function.

    get_directory.png

    The only problem is I don't know how to get the "OK" button to return the directory selected in the directory list-box. Here's my code:
    Code:
    void ClientResize(HWND hWnd, int nWidth, int nHeight)
    {
        RECT rcClient, rcWind;
        POINT ptDiff;
        GetClientRect(hWnd, &rcClient);
        GetWindowRect(hWnd, &rcWind);
        ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
        ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
        MoveWindow(hWnd, rcWind.left, rcWind.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
    }
    
    static UINT APIENTRY OFNHookProcOldStyle(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        if (uMsg == WM_INITDIALOG)
        {
            ClientResize(hWnd, 424, 255);
    
            RECT rect;
            GetWindowRect(hWnd, &rect);
            MoveWindow(hWnd, (GetSystemMetrics(SM_CXSCREEN) / 2) - ((rect.right - rect.left) / 2), (GetSystemMetrics(SM_CYSCREEN) / 2) - ((rect.bottom - rect.top) / 2), rect.right - rect.left, rect.bottom - rect.top, true);
    
            HWND bttn1 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Button", "OK")));
            HWND bttn2 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Button", "Cancel")));
            HWND list1 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "ListBox", NULL)));
            HWND list2 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, list1, "ListBox", NULL)));
            HWND label1 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Static", "File &name:")));
            HWND label2 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Static", "&Folders:")));
            HWND label3 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Static", "List files of &type:")));
            HWND label4 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Static", "Dri&ves:")));
            HWND label5 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, label2, "Static", NULL)));
            HWND cmbbx1 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "ComboBox", NULL)));
            HWND cmbbx2 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, cmbbx1, "ComboBox", NULL)));
            HWND txtbx1 = GetDlgItem(hWnd, GetDlgCtrlID(FindWindowEx(hWnd, NULL, "Edit", NULL)));
    
            SetWindowText(label1, "&Files: (*.*)");
            SetWindowText(label2, "&Directories:");
            SetWindowText(label3, "Directory &Name:");
            SetWindowText(label4, "D&rives:");
            EnableWindow(list1, FALSE);
            DestroyWindow(cmbbx1);
            DestroyWindow(txtbx1);
    
            MoveWindow(bttn1, 257, 225, 74, 27, true);
            MoveWindow(bttn2, 341, 225, 74, 27, true);
            MoveWindow(label1, 232, 56, 72, 16, true);
            MoveWindow(label2, 8, 56, 72, 16, true);
            MoveWindow(label3, 8, 8, 93, 16, true);
            MoveWindow(label4, 232, 176, 50, 16, true);
            MoveWindow(label5, 8, 24, 409, 16, true);
            MoveWindow(list1, 232, 72, 185, 93, true);
            MoveWindow(list2, 8, 72, 213, 123, true);
            MoveWindow(cmbbx2, 232, 192, 185, 19, true);
    
            ShowScrollBar(list1, SB_BOTH, FALSE);
            ShowScrollBar(list2, SB_BOTH, FALSE);
        }
    
        if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
        {
            PostMessage(hWnd, WM_COMMAND, IDABORT, 0);
            return TRUE;
        }
    
        return FALSE;
    }
    
    DLL char *get_directory(char *dname)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_dname = dname;
    
        tstring tstr_filter = widen("*.*|*.*|");
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_dname = widen(str_dname);
        tstring tstr_title = widen("Select Directory");
    
        WCHAR wstr_dname[MAX_PATH];
        wcsncpy_s(wstr_dname, tstr_dname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_dname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = tstr_title.c_str();
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_NONETWORKBUTTON | OFN_ENABLEHOOK | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
        ofn.lpfnHook = OFNHookProcOldStyle;
     
        GetOpenFileNameW(&ofn);
     
        DWORD attrib = GetFileAttributesW(wstr_dname);
    
        if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY))
        {
            static string result;
            result = shorten(wstr_dname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    Here's the code with syntax highlighting - https://pastebin.com/nYz31p4X

    @YellowAfterlife @Ghost in the IDE @zbox Anyone know how to do this?
     
    Last edited: Mar 15, 2018
  5. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,265
    I found out how to do it! Problem solved! Here's the code I'm using that got it working:
    Code:
    #include "stdafx.h"
    #include <windows.h>
    #include <Commdlg.h>
    #include <Shlobj.h>
    #include <wchar.h>
    #include <algorithm>
    #include <string>
    #include <vector>
    
    #define DLL extern "C" _declspec(dllexport)
    using namespace std;
    
    typedef basic_string<WCHAR> tstring;
    tstring widen(string str)
    {
        const size_t wchar_count = str.size() + 1;
        vector<WCHAR> buf(wchar_count);
        return tstring{ buf.data(), (size_t)MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buf.data(), wchar_count) };
    }
    
    string shorten(tstring str)
    {
        int nbytes = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length(), NULL, 0, NULL, NULL);
        vector<char> buf((size_t)nbytes);
        return string{ buf.data(), (size_t)WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length(), buf.data(), nbytes, NULL, NULL) };
    }
    
    DLL char *get_open_filename(char *filter, char *fname)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = NULL;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    
        if (GetOpenFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_save_filename(char *filter, char *fname)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = NULL;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
    
        if (GetSaveFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_open_filename_ext(char *filter, char *fname, char *dir, char *title)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
        string str_dir = dir;
        string str_title = title;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
        tstring tstr_dir = widen(str_dir);
        tstring tstr_title = widen(str_title);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = tstr_title.c_str();
        ofn.lpstrInitialDir = tstr_dir.c_str();
        ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    
        if (GetOpenFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_save_filename_ext(char *filter, char *fname, char *dir, char *title)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_filter = string(filter).append("||");
        string str_fname = fname;
        string str_dir = dir;
        string str_title = title;
    
        tstring tstr_filter = widen(str_filter);
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_fname = widen(str_fname);
        tstring tstr_dir = widen(str_dir);
        tstring tstr_title = widen(str_title);
    
        WCHAR wstr_fname[MAX_PATH];
        wcsncpy_s(wstr_fname, tstr_fname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = wstr_fname;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = tstr_title.c_str();
        ofn.lpstrInitialDir = tstr_dir.c_str();
        ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
    
        if (GetSaveFileNameW(&ofn) != 0)
        {
            static string result;
            result = shorten(wstr_fname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    void ClientResize(HWND hWnd, int nWidth, int nHeight)
    {
        RECT rcClient, rcWind;
        POINT ptDiff;
        GetClientRect(hWnd, &rcClient);
        GetWindowRect(hWnd, &rcWind);
        ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
        ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
        MoveWindow(hWnd, rcWind.left, rcWind.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
    }
    
    WCHAR wstr_dname[MAX_PATH];
    
    UINT APIENTRY OFNHookProcOldStyle(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        if (uMsg == WM_INITDIALOG)
        {
            ClientResize(hWnd, 424, 255);
    
            RECT rect;
            GetWindowRect(hWnd, &rect);
            MoveWindow(hWnd, 
                (GetSystemMetrics(SM_CXSCREEN) / 2) - ((rect.right - rect.left) / 2), 
                (GetSystemMetrics(SM_CYSCREEN) / 2) - ((rect.bottom - rect.top) / 2), 
                rect.right - rect.left, rect.bottom - rect.top, TRUE);
    
            HWND bttn1 = GetDlgItem(hWnd, IDOK);
            HWND bttn2 = GetDlgItem(hWnd, IDCANCEL);
            HWND list1 = GetDlgItem(hWnd, 1120);
            HWND list2 = GetDlgItem(hWnd, 1121);
            HWND label1 = GetDlgItem(hWnd, 1090);
            HWND label2 = GetDlgItem(hWnd, 65535);
            HWND label3 = GetDlgItem(hWnd, 1089);
            HWND label4 = GetDlgItem(hWnd, 1091);
            HWND label5 = GetDlgItem(hWnd, 1088);
            HWND cmbbx1 = GetDlgItem(hWnd, 1136);
            HWND cmbbx2 = GetDlgItem(hWnd, 1137);
            HWND txtbx1 = GetDlgItem(hWnd, 1152);
    
            SetWindowText(label1, "&Files: (*.*)");
            SetWindowText(label2, "&Directories:");
            SetWindowText(label3, "Directory &Name:");
            SetWindowText(label4, "D&rives:");
            DestroyWindow(cmbbx1);
            DestroyWindow(txtbx1);
    
            MoveWindow(bttn1, 256, 224, 77, 27, TRUE);
            MoveWindow(bttn2, 340, 224, 77, 27, TRUE);
            MoveWindow(label1, 232, 56, 72, 16, TRUE);
            MoveWindow(label2, 8, 56, 72, 16, TRUE);
            MoveWindow(label3, 8, 8, 93, 16, TRUE);
            MoveWindow(label4, 232, 176, 50, 16, TRUE);
            MoveWindow(label5, 8, 24, 409 * 100, 16, TRUE);
            MoveWindow(list1, 232, 72, 185, 93, TRUE);
            MoveWindow(list2, 8, 72, 213, 123, TRUE);
            MoveWindow(cmbbx2, 232, 192, 185, 19, TRUE);
    
            DlgDirListW(hWnd, wstr_dname, 1120, 1088, DDL_ARCHIVE | DDL_READWRITE | DDL_READONLY);
            PostMessageW(hWnd, WM_SETFOCUS, 0, 0);
        }
    
        if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
        {
            HWND label1 = GetDlgItem(hWnd, 1090);
            HWND label2 = GetDlgItem(hWnd, 65535);
            HWND label3 = GetDlgItem(hWnd, 1089);
            HWND label4 = GetDlgItem(hWnd, 1091);
            HWND label5 = GetDlgItem(hWnd, 1088);
    
            GetDlgItemTextW(hWnd, 1088, wstr_dname, MAX_PATH);
            PostMessageW(hWnd, WM_COMMAND, IDABORT, 0);
            return TRUE;
        }
    
        if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL)
        {
            tstring tstr_dname = widen("");
            wcsncpy_s(wstr_dname, tstr_dname.c_str(), MAX_PATH);
            PostMessageW(hWnd, WM_COMMAND, IDABORT, 0);
            return TRUE;
        }
    
        if (uMsg == WM_CLOSE)
        {
            tstring tstr_dname = widen("");
            wcsncpy_s(wstr_dname, tstr_dname.c_str(), MAX_PATH);
            PostMessageW(hWnd, WM_COMMAND, IDABORT, 0);
            return TRUE;
        }
    
        return FALSE;
    }
    
    DLL char *get_directory(char *dname)
    {
        OPENFILENAMEW ofn;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_dname = dname;
    
        tstring tstr_filter = widen("*.*|*.*|");
        replace(tstr_filter.begin(), tstr_filter.end(), '|', '\0');
        tstring tstr_dname = widen(str_dname);
        tstring tstr_title = widen("Select Directory");
        tstring tstr_empty = widen("");
    
        if (tstr_dname == tstr_empty)
            GetCurrentDirectoryW(MAX_PATH, wstr_dname);
        else
            wcsncpy_s(wstr_dname, tstr_dname.c_str(), MAX_PATH);
    
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = SitehWnd;
        ofn.lpstrFile = NULL;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = tstr_filter.c_str();
        ofn.nFilterIndex = 0;
        ofn.lpstrTitle = tstr_title.c_str();
        ofn.lpstrInitialDir = wstr_dname;
        ofn.Flags = OFN_NONETWORKBUTTON | OFN_ENABLEHOOK | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES;
        ofn.lpfnHook = OFNHookProcOldStyle;
    
        GetOpenFileNameW(&ofn);
    
        DWORD attrib = GetFileAttributesW(wstr_dname);
    
        if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY))
        {
            static string result;
            result = shorten(wstr_dname);
            return (char *)result.c_str();
        }
    
        return (char *)"";
    }
    
    DLL char *get_directory_alt(char *capt, char *root)
    {
        BROWSEINFOW bi;
    
        HWND SitehWnd;
        SitehWnd = GetAncestor(GetActiveWindow(), GA_ROOTOWNER);
    
        string str_capt = capt;
        string str_root = root;
    
        tstring tstr_capt = widen(str_capt);
        tstring tstr_root = widen(str_root);
        tstring tstr_empty = widen("");
        tstring tstr_zero = widen("0");
    
        LPITEMIDLIST pstr_root;
    
        if (tstr_root == tstr_empty)
            SHParseDisplayName(tstr_zero.c_str(), 0, &pstr_root, 0, 0);
        else
            SHParseDisplayName(tstr_root.c_str(), 0, &pstr_root, 0, 0);
    
        WCHAR wstr_dir[MAX_PATH];
    
        ZeroMemory(&bi, sizeof(bi));
        bi.hwndOwner = SitehWnd;
        bi.pidlRoot = pstr_root;
        bi.pszDisplayName = wstr_dir;
        bi.lpszTitle = tstr_capt.c_str();
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON;
    
        LPITEMIDLIST lpItem = SHBrowseForFolderW(&bi);
        if (lpItem != NULL)
        {
            if (SHGetPathFromIDListW(lpItem, wstr_dir) == 0)
                return (char *)"";
            else
            {
                static string result;
                result = shorten(wstr_dir);
                return (char *)result.c_str();
            }
        }
    
        return (char *)"";
    }
    And here's the code shown above, but with syntax highlighting - https://pastebin.com/n5JS3XaC
     
    Last edited: Mar 18, 2018

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice