?

Log in

No account? Create an account

Previous Entry | Next Entry

Выбор каталога

В виндах есть диалог для выбора каталога SHBrowseForFolder. В работе сие позорище выглядит так:



Не буду объяснять, насколько оно неудобно - если разок столкнетесь, то поймете на опыте.

Вместо этого хотелось бы иметь диалог, подобный тем, что дают функции GetSaveFileName/GetOpenFileName. Что-то в таком роде:



Осталось понять, как этого добиться - ведь те функции позволяют выбрать файл, а не фолдер. Под катом решение, опробованное на работоспособность под Win XP и Win 7. Можно прямо копипастить.


//ага, просто static, без выпендрежа
static WNDPROC wProcBase;
static char getFolderNameResult[_MAX_PATH];

//функция для субклассинга
LRESULT CALLBACK wProcNew(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	if (msg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK) 
	{
                //сохраняем путь в lpstrFile и выходим
		SendMessage(hwnd, CDM_GETFILEPATH, _MAX_PATH, (LPARAM)getFolderNameResult);

                //здесь можно проверить getFolderNameResult если надо чтобы это был существующий каталог, например так:
   	        struct _stat buffer;
                if (0 == _stat(fname, &buffer) && 0 != (buffer.st_mode & _S_IFDIR))
      		    EndDialog(hwnd, IDOK);
		return 0;
	}
        //вызов прежнего обработчика
	return CallWindowProc(wProcBase, hwnd, msg, wParam, lParam);
}

//Hook-функция для диалога
static UINT_PTR CALLBACK OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
	if (uiMsg == WM_INITDIALOG)
	{
                //hdlg - это не сам диалог, а его child, так что на шаг вверх
		HWND par= (HWND)GetWindowLong(hdlg, GWL_HWNDPARENT);
                //субклассинг
		wProcBase= (WNDPROC)GetWindowLong(par, GWL_WNDPROC);
		SetWindowLong(par, GWL_WNDPROC, (LONG)wProcNew);
                //скрываем лишние контролы, на некоторых меняем надпейси
		SendMessage(par, CDM_HIDECONTROL, cmb1, NULL);
		SendMessage(par, CDM_HIDECONTROL, stc2, NULL);
		SendMessage(par, CDM_SETCONTROLTEXT, stc3, (LPARAM)"Folder:");
		SendMessage(par, CDM_SETCONTROLTEXT, IDOK, (LPARAM)"Accept");
		SendMessage(par, CDM_SETCONTROLTEXT, stc4, (LPARAM)"In folder:");
		return 0;
	}
	return 0;
}

//на входе надо заполнить ofn так, как будто хотим сохранить файл
//в каталоге. на выходе результат будет в ofn->lpstrFile.
int GetFolderName(OPENFILENAME *ofn)
{
    ofn->Flags|= OFN_EXPLORER|OFN_ENABLEHOOK;
    ofn->lpfnHook= OFNHookProc;
    ofn->lpstrCustomFilter= NULL;
    ofn->nFilterIndex= 0;
    ofn->lpstrFilter= " \0:\0\0"; //фильтр, который гарантирует показ только каталогов, но не файлов
    ofn->lpstrTitle= "Select Folder...";
    int r= GetSaveFileName(ofn);
    strcpy(ofn->lpstrFile, getFolderNameResult);
    ofn->nFileOffset= (WORD)strlen(getFolderNameResult);
    return r;
}


Comments

( 40 comments — Leave a comment )
ex_leo_sosn
Feb. 3rd, 2010 04:40 pm (UTC)
Точно, позорище. Всегда хочется кого-нибудь убить, если приходится что-то делать с такого рода позорищами, которых в винде не счесть...
psilogic
Feb. 3rd, 2010 06:03 pm (UTC)
линуксоид? ;))
ex_leo_sosn
Feb. 3rd, 2010 07:53 pm (UTC)
Ну разве что начинающий, да и не линуксоид, а бсдоид.

Админить один хрен приходится венду, и так она меня достала, так достала. И видя, в каком направлении они это дело развивают, трудно становится связывать своё будущее с мелкомягкой продукцией. Слишком много маразма и слишком часто беспричинно всё меняется.
psilogic
Feb. 3rd, 2010 07:59 pm (UTC)
Ну Windows 7 ничего так. Хотя тот диалог остался убогим и под семеркой :)
(no subject) - ex_leo_sosn - Feb. 3rd, 2010 08:22 pm (UTC) - Expand
(no subject) - psilogic - Feb. 3rd, 2010 08:28 pm (UTC) - Expand
(no subject) - ex_leo_sosn - Feb. 3rd, 2010 08:49 pm (UTC) - Expand
(no subject) - psilogic - Feb. 3rd, 2010 09:51 pm (UTC) - Expand
(no subject) - gaussrifle - Feb. 6th, 2010 08:04 am (UTC) - Expand
(no subject) - ex_leo_sosn - Feb. 6th, 2010 08:15 am (UTC) - Expand
(no subject) - ex_leo_sosn - Feb. 6th, 2010 08:19 am (UTC) - Expand
(no subject) - gaussrifle - Feb. 6th, 2010 09:40 am (UTC) - Expand
(no subject) - ex_leo_sosn - Feb. 6th, 2010 10:00 am (UTC) - Expand
(no subject) - gaussrifle - Feb. 6th, 2010 11:11 am (UTC) - Expand
(no subject) - psilogic - Feb. 6th, 2010 10:15 am (UTC) - Expand
(no subject) - gaussrifle - Feb. 6th, 2010 11:12 am (UTC) - Expand
(no subject) - psilogic - Feb. 6th, 2010 11:20 am (UTC) - Expand
geo_graphit
Feb. 3rd, 2010 07:26 pm (UTC)
...а самодельный диалог..не пробовали...
psilogic
Feb. 3rd, 2010 08:04 pm (UTC)
Пробовал. Для ускоренного выбора файлов у мня такой зверек:

http://psi-logic.shadanakar.org/images/pickfile.png

Можно сделать его вариант под выбор каталогов, но это будет уже излишеством.
0serg
Feb. 3rd, 2010 07:30 pm (UTC)
Стоит ли вообще пользоваться WinAPI? Даже M$ вроде бы уже несколько лет предлагает худо-бедно сносные альтернативы
psilogic
Feb. 3rd, 2010 08:09 pm (UTC)
Тут возникает вопрос, а какая именно альтернатива принципиально лучше WinAPI (ну или MFC - невелика разница)? QT - понятно, но, мультиплатформенность не требуется.
0serg
Feb. 3rd, 2010 10:05 pm (UTC)
Ну, скажем Мелкософт сейчас предлагает WFP. Я им не пользовался, но по впечатлениям - они слизали структуру библиотеки с Qt, постаравшись обеспечить такой же уровень удобства.

Кроме того, Qt - прекрасный выбор и для одноплатформенных приложений. Дорогой только, зараза, для коммерческого использования.
psilogic
Feb. 3rd, 2010 10:18 pm (UTC)
Что за хрень такая WFP?

QT юзать можно, и я ее юзаю там, где она прокатывает, но в данном случае не годится. Мультиплаформенность QT поюзать не получится, т.к. там работа со звуком, завязанная на виндовую архитектуру (у самой QT звуковая библиотека какая-то левая и крошечная). А оконные фишечки-рюшечки от QT в данном случае не требуются, т.к. они уже реализованы в либе над WinSDK.
(no subject) - 0serg - Feb. 3rd, 2010 10:39 pm (UTC) - Expand
(no subject) - psilogic - Feb. 3rd, 2010 11:00 pm (UTC) - Expand
(no subject) - 0serg - Feb. 4th, 2010 07:12 pm (UTC) - Expand
(no subject) - psilogic - Feb. 4th, 2010 10:27 pm (UTC) - Expand
(no subject) - 0serg - Feb. 6th, 2010 07:22 am (UTC) - Expand
(no subject) - psilogic - Feb. 6th, 2010 09:07 am (UTC) - Expand
(no subject) - 0serg - Feb. 4th, 2010 07:31 pm (UTC) - Expand
wizzard0
Feb. 3rd, 2010 10:02 pm (UTC)
странно, вроде начиная с common controls v6 идет именно такой диалог, как вы описали...
psilogic
Feb. 3rd, 2010 10:10 pm (UTC)
второй он из v6 и есть (видите кнопки округлые?)

просто чуть подправленный, чтобы выбирать не файлы, а папки
wizzard0
Feb. 3rd, 2010 10:36 pm (UTC)
Да, я ж именно о выборе папок говорю. А хотя нет, постойте, это нужны common controls 6 и vista and up. простите.
psilogic
Feb. 3rd, 2010 10:49 pm (UTC)
Под windows 7 та же хрень, просто с прозрачными заголовками - красиво, но по прежнему неудобно :(
wizzard0
Feb. 3rd, 2010 10:52 pm (UTC)
Да ну?
(no subject) - psilogic - Feb. 3rd, 2010 11:06 pm (UTC) - Expand
(no subject) - wizzard0 - Feb. 3rd, 2010 11:10 pm (UTC) - Expand
(no subject) - psilogic - Feb. 3rd, 2010 11:18 pm (UTC) - Expand
(no subject) - wizzard0 - Feb. 3rd, 2010 11:19 pm (UTC) - Expand
(no subject) - psilogic - Feb. 3rd, 2010 11:31 pm (UTC) - Expand
( 40 comments — Leave a comment )

Profile

ioda
psilogic
Мирослав Войнаровский
Психологика

Latest Month

September 2019
S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     
Powered by LiveJournal.com
Designed by yoksel