psilogic: (Default)
[personal profile] psilogic
В виндах есть диалог для выбора каталога 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;
}


Date: 2010-02-03 04:40 pm (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Точно, позорище. Всегда хочется кого-нибудь убить, если приходится что-то делать с такого рода позорищами, которых в винде не счесть...

Date: 2010-02-03 06:03 pm (UTC)
From: [identity profile] psilogic.livejournal.com
линуксоид? ;))

Date: 2010-02-03 07:53 pm (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Ну разве что начинающий, да и не линуксоид, а бсдоид.

Админить один хрен приходится венду, и так она меня достала, так достала. И видя, в каком направлении они это дело развивают, трудно становится связывать своё будущее с мелкомягкой продукцией. Слишком много маразма и слишком часто беспричинно всё меняется.

Date: 2010-02-03 07:59 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Ну Windows 7 ничего так. Хотя тот диалог остался убогим и под семеркой :)

Date: 2010-02-03 08:22 pm (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Да та же Виста, ничё почти к лучшему не поменялось.

Наглядный пример, кстати, насколько народный опинион зависит от рекламной шумихи. Типа, Виста была отстоем, а семёрка неплоха. Но это бред, семёрка это та же Виста с другим скином.

Date: 2010-02-03 08:28 pm (UTC)
From: [identity profile] psilogic.livejournal.com
висту тоже нехило рекламировали
просто ко времени выхода семерки в ней пофиксили баги :)

Date: 2010-02-03 08:49 pm (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Их не надо было создавать, для начала. Я не понимаю, куда они прут. Сделал хорошую ОС -- молодец. Развивай направление, привязывай клиента. Нет, не буу. Всё перебуроблю. Были песочные часы -- получите кольцо. Были документс энд сеттингс (а ещё до этого профайлс) получите усерс. И так далее до бесконечности. Нахрена менять шило на мыло? Для админа это один непрекращающийся головняк, особенно если машины с разными осями.

Неясно зачем убирать удачные решения. Типа кнопки "вверх". Или запуск из-под любого юзера по правой кнопке.

По логике, каждая последующая ос должна те же самые функции выполнять лучше и быстрее. Но куда там. Допустим, вот, терминальные сервисы в 2003 работают побыстрее, чем в 2000. Но что Виста, что семёрка, пользы почти нет, а памяти жрут и тормозят на порядок круче предыдущих. Спрашивается, а нахрена.

Простым людям этот отстой проталкивают в горло грязным ботинком. Типа, ноутбучок захотел? Тока с Вистой (или семёркой). Захотел снести и поставить экспишку? А хрен тебе дров.

А бизнесы, которые слушают относительно вменяемых онолитегов, на 80% проигнорили Висту, и семёрку, возможно, будут игнорить на схожий процент. И правильно сделают, ИМХО.

Потому как бабло. Расходы на внедрение есть. Прибытка от повышения эффективности работы сотрудников нет. Так нахера?

Вот и ставят её тока партнёры Майкрософт, т.к. через шантаж. Да и то не все. Интел послал их, например, с этими дурацкими приколами...

Date: 2010-02-03 09:51 pm (UTC)
From: [identity profile] psilogic.livejournal.com
а чо за "кнопка вверх?"

шо касается эффективности, то дома я работаю под триальной семеркой - т.к. есть выбор
красивая она сцука, завораживает :) и вполне удобная - чего только стоит железно срабатывающий из под всяких висяков alt-ctrl-del

Date: 2010-02-06 08:04 am (UTC)
From: [identity profile] gaussrifle.livejournal.com
все дело в деньгах.

Майкрософт имеет бабло не только с продаж ОС но и с обучения и с подтверждения знаний(сертификат) админа.

Чем больше продуктов - тем больше вам-админам придется платить деньги за обучение и сдачу экзаменов.

Байка откуда берутс баги:
Мой папа - железнодорожник и он рассказывал, что в советское время было несколько НИИ для нужд ЖД. Они там разрабатывали всякие приспособления, в том числе башмак(клин) для подкладки его под колесо поезда при необходимости стояночной фиксации.
Так вот, для всех этих НИИ был предусмотрен план постоянного повышения эфективности. Но как это выполнить? Так что делали: Заранеее запроектировали башмак гиганствкого размера. И каждый год делали его на 100 граммов легче. В масштабах страны- это гигантская экономия материала, но почему-бы сразу не запроектировать его без ошибок-нужного размера?
А есть то на что? А премии?

А другие люди потом на местах получали преммии за изобретельство-рационализаторство - ведь можно спилить лишний вес и насверлить в нем дырок - тем самыс облегчить работу путейцев, которые таскают их вручную.

Так же и майкрософт - будучи монополистом заранее делают необходимые ошибки, чтобы иметь работу и потом их исправлять.

Date: 2010-02-06 08:15 am (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Хорошая байка, может они действительно поэтому всё постоянно меняют, а админы с каждой, буквально с каждой новой версией продукта мучаются.

А что касается сертификации админов, то выходит, что такие админы дураки, потому как их обувают, а они и рады. Значит, выходит, что и я дурак.

Как дальше жить?

Date: 2010-02-06 08:19 am (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Кстати, как-то проходил второй фоллаут с гаусс райфлом. Высокая перцепция давала высокий сиквенс, начинал всегда первым и следующий ход был за мной. Максимальный аджилити позволял стрелять из гаусс райфла два раза за ход прицельно.

Итого: встреча с энклэйв патролом, первые два хода мои, к началу действий энклэйв патрола четверо из них уже отправились в верхний вэйстланд...

Date: 2010-02-06 09:40 am (UTC)
From: [identity profile] gaussrifle.livejournal.com
А со мной еще Кесседи был и тоже с гаусовкой. Жалко на метерикое к гауссовке патронов всего 50 было у двух охранников великого дракона и добыча этих 50-ти патронов стоила жизни всему китайскому населению Сан-Франциско :)

Date: 2010-02-06 10:00 am (UTC)
From: [identity profile] leo-sosnine.livejournal.com
Кэссиди не стоит давать гауссовку из-за нехватки патронов. Маловато хитов он из неё вышибает, тока патроны переводить. Вообще, следует признать, что во втором фоллауте если играть боевым персонажем, то команда только мешает. Лезут на амбразуры, постоянно попадают под очередь из минигана, дамэйдж выдают просто никакой по сравнению с прокаченным персом.

Патроны для гауссовки продаёт верхний продавец в сан-фране у входа, правда, у него обновляются они редко, приходится ждать.

Date: 2010-02-06 11:11 am (UTC)
From: [identity profile] gaussrifle.livejournal.com
Спасибо! Жаль я не знал этого 12 лет назад.

Date: 2010-02-06 10:15 am (UTC)
From: [identity profile] psilogic.livejournal.com
чо та из второго фаллаута запомнились тока муравьи, плюющаяся колючками трава и взорванный туалет =)

Date: 2010-02-06 11:12 am (UTC)
From: [identity profile] gaussrifle.livejournal.com
взорваный туалет это да!

А ты могилы выкапивал?

Date: 2010-02-06 11:20 am (UTC)
From: [identity profile] psilogic.livejournal.com
че та не помню такого...

Date: 2010-02-03 07:26 pm (UTC)
From: [identity profile] geo-graphit.livejournal.com
...а самодельный диалог..не пробовали...

Date: 2010-02-03 08:04 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Пробовал. Для ускоренного выбора файлов у мня такой зверек:

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

Можно сделать его вариант под выбор каталогов, но это будет уже излишеством.

Date: 2010-02-03 07:30 pm (UTC)
From: [identity profile] 0serg.livejournal.com
Стоит ли вообще пользоваться WinAPI? Даже M$ вроде бы уже несколько лет предлагает худо-бедно сносные альтернативы

Date: 2010-02-03 08:09 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Тут возникает вопрос, а какая именно альтернатива принципиально лучше WinAPI (ну или MFC - невелика разница)? QT - понятно, но, мультиплатформенность не требуется.

Date: 2010-02-03 10:05 pm (UTC)
From: [identity profile] 0serg.livejournal.com
Ну, скажем Мелкософт сейчас предлагает WFP. Я им не пользовался, но по впечатлениям - они слизали структуру библиотеки с Qt, постаравшись обеспечить такой же уровень удобства.

Кроме того, Qt - прекрасный выбор и для одноплатформенных приложений. Дорогой только, зараза, для коммерческого использования.

Date: 2010-02-03 10:18 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Что за хрень такая WFP?

QT юзать можно, и я ее юзаю там, где она прокатывает, но в данном случае не годится. Мультиплаформенность QT поюзать не получится, т.к. там работа со звуком, завязанная на виндовую архитектуру (у самой QT звуковая библиотека какая-то левая и крошечная). А оконные фишечки-рюшечки от QT в данном случае не требуются, т.к. они уже реализованы в либе над WinSDK.

Date: 2010-02-03 10:39 pm (UTC)
From: [identity profile] 0serg.livejournal.com
Упс, опечатка. WPF = Windows Presentation Foundation, часть .NET 3.0

Qt вполне можно использовать и совместно с Windows-only кодом. Если Phonon-а не хватает (кстати, а что за работа со звуком?), то пишешь свой класс в рамках Qt-тулкита, обеспечивающий нужную обертку над виндовыми функциями. Подобный враппер - это очень хороший паттерн.

Date: 2010-02-03 11:00 pm (UTC)
From: [identity profile] psilogic.livejournal.com
WPF в MSDN упоминается под C# и Visual Basic. А под C++ оно есть?

Да, я про фонон и говорю - нечто мелкое, стороннее и непонятное... даже функций записи звука не видно.

Насчет Qt зачем мне wrapper - только ради того, чтобы присобачить к программе 15 Mb qt-шных DLL-ек? Какой предполагается бонус? Собственно, я с этого начал - какой бонус...

Date: 2010-02-04 07:12 pm (UTC)
From: [identity profile] 0serg.livejournal.com
Упс, пишут что действительно нет. Вроде как можно прикрутить криво, но в целом - M$ поступила в "лучших" своих традициях (внутри WPF - C++)

Функции записи звука большинству и не нужны... обычно требуется обеспечить лишь playback, а с этим у фонона все в порядке.

Qt в дистрибутиве к софту у меня составлял 4 Мб. Не мало, но и не сказать чтобы очень много. Зато использование Qt резко ускоряет процесс разработки - по моему опыту, на то, что в MFC в уже существующем и хорошо отлаженном проекте с обширным SDK уходит целый день, в Qt в совершенно чистом проекте делается за 2 часа... и с лучшим качеством в итоге. Поэтому если вопрос лишних 4 мб в дистрибутиве не стоит - то смысл использовать Qt есть.

Но wrapper был упомянут здесь в другом контексте. Использовать нативный WinAPI непосредственно из основного тела программы - в любом случае плохая идея. Нормальным подходом является создать специализированный объект, занимающийся обработкой, скажем, звука, и инкапсулирующий в себя вызовы системных функций. А этот объект далее уже что в Qt, что в MFC проект вставляется идентично. Причем говоря о о записи звука, в Qt библиотеку записи основанную на нативном API, как мне кажется, удастся сигналами и слотами реализовать намного удобнее и красивее.

Date: 2010-02-04 10:27 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Жалко, что нет простого вызова из c++ - хренька-то красивая :)

[ Функции записи звука большинству и не нужны ]

Я понимаю. Но мне то нужны. Это вполне нормально, Qt - не библиотека для работы со звуком, у нее задачи не те, а со своими задачами она вполне справляется.

Использование Qt, само собой, ускоряет процесс разработки - по сравнению с MFC. Но не по сравнению с либой, в которой уже реализовано все то, что хотелось бы от Qt. WinAPI - функции нижнего уровня, ессно, никто их не вызывает из "тела" верхнего уровня. Тот код, что я привел здесь, это нижний уровень моей либы.

Сигналы и слоты для обработки звука - это даже не смешно...

Date: 2010-02-06 07:22 am (UTC)
From: [identity profile] 0serg.livejournal.com
Но не по сравнению с либой, в которой уже реализовано все то, что хотелось бы от Qt.

А чего хотелось бы от Qt? Запись звука, как оказалось, там уже есть, и в планах разработчиков сделать по image/sound aquisition нормальный большой framework.

Тот код, что я привел здесь, это нижний уровень моей либы.

Ну так либу-то пришлось самому в итоге писать. Хорошие либы - на удивление большая редкость, особенно когда use-case чуть отличается от предусмотренного разработчиками, и в либе "чуть-чуть" чего-то надо докрутить, чтобы все было хорошо

Сигналы и слоты для обработки звука - это даже не смешно...

А это ты зря. Оверхед у Qt-шной реализации крайне низкий, и сигнализировать ими о окончании записи блока - дешевая операция. Если нужно, к примеру, визуализировать поток (записываемый или воспроизводимый) аудио в виде графика, то подобная реализация близка к оптимальной.

Date: 2010-02-06 09:07 am (UTC)
From: [identity profile] psilogic.livejournal.com
[ А чего хотелось бы от Qt? ]

Собственно, звука как раз особо и не хотелось, так как данный проект как раз связан с обработкой звука. А хотелось бы удобных окон и layout-ов - ну вот как тот диалог выбора каталога например. Но, поскольку в либе уже есть порядка 30 layout-ов, то 5 Qt-шных layout-ов как-то не особо необходимы :)

[ Ну так либу-то пришлось самому в итоге писать. ]

Ну это не так сложно, поскольку эту либу не надо делать на все случаи жизни (use-case). А потом, когда либа уже есть и требуется новая функциональность... проще добавить что-то в либу, чем искать где-то стороннюю либу.

[ Оверхед у Qt-шной реализации крайне низкий ]

Да дело не столько в оверхеде, а в том, что в данной задачке без разницы, какой механизм синхронизации использовать.

Date: 2010-02-04 07:31 pm (UTC)
From: [identity profile] 0serg.livejournal.com
Да, кстати, оказалось что в последней версии (4.6) появилась и поддержка записи аудио (QAudioInput). Сделано пока не очень красиво, но все же несопоставимо лучше того WinAPI, который я когда-то для этих целей использовал

Date: 2010-02-03 10:02 pm (UTC)
wizzard: (Default)
From: [personal profile] wizzard
странно, вроде начиная с common controls v6 идет именно такой диалог, как вы описали...

Date: 2010-02-03 10:10 pm (UTC)
From: [identity profile] psilogic.livejournal.com
второй он из v6 и есть (видите кнопки округлые?)

просто чуть подправленный, чтобы выбирать не файлы, а папки

Date: 2010-02-03 10:36 pm (UTC)
wizzard: (Default)
From: [personal profile] wizzard
Да, я ж именно о выборе папок говорю. А хотя нет, постойте, это нужны common controls 6 и vista and up. простите.

Date: 2010-02-03 10:49 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Под windows 7 та же хрень, просто с прозрачными заголовками - красиво, но по прежнему неудобно :(

Date: 2010-02-03 10:52 pm (UTC)
wizzard: (Default)
From: [personal profile] wizzard
Да ну?

Date: 2010-02-03 11:06 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Дык, так выглядит под семеркой вызов GetSaveFileName. Но в MSDN-е не видно подходящих опций, чтобы подкорректировать внешний вид диалога - сделать выбор фолдера как на скриншоте. Этот скриншот откуда взят?

Date: 2010-02-03 11:10 pm (UTC)
wizzard: (Default)
From: [personal profile] wizzard
Там написано :)

Libraries - Choose library locations - Add folder

А что такое GetSaveFileName? :)))

Date: 2010-02-03 11:18 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Эээ... проехали :))

Date: 2010-02-03 11:31 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Просто до меня не сразу дошло, что мы с вами о совершенно разных вещах говорим - в о том, что оно где-то реализовано (неизвестно, как), а я - о том, как именно его реализовать. Например, тот диалог, что на вашем скриншоте, он есть в эксплорере Windows 7, но вопрос в том, как его вызвать программно.
Page generated Aug. 13th, 2025 03:05 am
Powered by Dreamwidth Studios