Дорога к Любви, Успеху и Богатству! 
Каждый в своей жизни когда-либо хотел быть Любимым, или достичь выдающихся Успехов на работе и не только. А есть ли кто-нибудь, кто никогда не желал бы стать финансово независимым человеком, чтобы свободно распоряжаться своим самым драгоценным ресурсом – временем? 
Если это не Вы, то Вам незачем заходить к нам на сайт…


Ещe больше окон!

Просто Строители

Ни одно включение компьютера, на котором установлена ОС Windows, не обходится без того, чтобы перед нами не возникали различные окна, с помощью которых операционная система организует диалог с пользователем или обозначает какие-либо длительные процессы, не давая, таким образом, усомниться в своей работоспособности на данный момент.

Это, в свою очередь, определяет вполне конкретный стандарт, которого следует придерживаться при написании программ, запускаемых под Windows. Понятно, что пользователю намного проще разобраться с работой программы, если перед ним появляются все те же стандартные окна, постоянно встречающиеся и в других приложениях. Например, всем привычны окна навигации по файловому пространству, которые мы видим в "Проводнике", диалоги открытия или сохранения документа в Word`е.

Описанию методов добавления подобных окон в свои программы при работе в среде Borland C++ Builder и посвящена данная статья.

Сразу отметим, что в данной статье мы не будем касаться приемов работы непосредственно с компонентами из вкладки Dialogs, которые дают возможность удивительно просто вводить в свою программу разнообразнейшие диалоговые окна. Наша цель - малоизвестные VCL-функции, а также наборы функций из API (Application Programming Interface) - Интерфейса Прикладного Программирования.

Для совсем начинающих поясним: API представляет собой огромную коллекцию из сотен Си-функций и структур. Применение их дает возможность наиболее полно использовать функциональные возможности операционной системы и аппаратные средства компьютера. Как правило, доступ к этим функциям и структурам носит глобальный характер и лишь иногда требует подключения заголовочных файлов и библиотек.

Окна, позволяющие выбрать директорию

1Подобные окна используются в случае, когда необходимо скопировать или переместить файл из одной директории в другую. Попробуем для этого воспользоваться функцией SelectDirectory. Результат ее действия можно увидеть на рис.1.

Согласитесь, вид такого окна вряд ли способен придать элемент профессионализма программе, особенно на фоне Windows XP, но, тем не менее, функционально свои задачи оно выполняет. И если вас не оттолкнул трогательный примитивизм в стиле Windows 3.11, то приведенный ниже код будет небесполезен:

#include
const SELDIRHELP = 1000;
::::::::::
AnsiString NameOfDir = "C:\\Windows";
SelectDirectory (NameOfDir, TSelectDirOpts() << sdAllowCreate << sdPerformCreate << sdPrompt, SELDIRHELP);

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

Намного приятней, с эстетической точки зрения, выглядит окно, которое мы видим на рис.2.

2Чтобы обеспечить его появление, услуг VCL окажется уже маловато, да и поработать придется не только мышкой, но и клавиатурой:

#define NO_WIN32_LEAN_AND_MEAN
#include
::::::::::::::::::::
BROWSEINFO bi;
ZeroMemory(&bi,sizeof(BROWSEINFO));
char lpBuffer [MAX_PATH]={0};
LPITEMIDLIST pidlBrowse;
ZeroMemory(&pidlBrowse,sizeof(LPITEMID-LIST));
bi.hwndOwner = Handle;
bi.pszDisplayName = lpBuffer;
bi.lpszTitle = "Cool window";
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = 0;
pidlBrowse = SHBrowseForFolder(&bi);
if (pidlBrowse != NULL)
{

// В lpBuffer содержится имя выбранной
//папки. Показываем его

MessageBox(NULL, lpBuffer, "Display name", MB_OK);

if (SHGetPathFromIDList(pidlBrowse,lpBuf-fer))
//Теперь в lpBuffer содержится уже
//полный путь к выбранной папке

MessageBox(NULL, lpBuffer, "Display full name", MB_OK);
}

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

Окна, позволяющие выбрать файл

3Довольно часто в программе требуется предоставить пользователю возможность выбрать определенный файл. Для этих целей служат компоненты TOpenDialog и TSaveDialog из вкладки Dialogs в "Палитре" "Компонент". Но оказывается, чтобы вызвать окна, позволяющие сохранять или открывать файлы, достаточно VCL-функции PromptForFileName (рис.3), при этом код программы остается таким же компактным, как и в случае использования вышеназванных компонент:

AnsiString NameOfFile;
PromptForFileName (NameOfFile, "All files (*.*)|*.*", "*.dat", "Вызвано без использования компонент", "C:\\", false);
ShowMessage(NameOfFile);

Полное имя файла, как нетрудно догадаться, содержит строковая переменная NameOfFile. Второй и третий параметр задают, соответственно, фильтр по расширению при отображении списка файлов и расширение по умолчанию, присоединяющееся к имени файла при положительном завершении диалога. Последний параметр в PromptForFileName определяет, какой диалог будет вызван. Когда он равен истине, то мы получаем стандартный диалог сохранения файла, в противном случае - открытия.

Безусловно, вызов подобных диалоговых окон можно реализовать и не используя VCL. Для этого API предлагает нам функции

GetOpenFileName, GetSaveFileName и структуру OPENFILENAME:
char buff[MAX_PATH]={0};
OPENFILENAME lopen;
ZeroMemory(&lopen,sizeof(OPENFILENAME));
lopen.lStructSize=sizeof(OPENFILENAME);
lopen.hwndOwner=Handle;
lopen.lpstrFilter="All files(*.*)\0*.*\0Text files(*.txt)\0*.TXT\0";
lopen.lpstrFile=buff;
lopen.nMaxFile=MAX_PATH;
lopen.nFilterIndex = 1;
lopen.lpstrTitle="Open dialog with help API";
lopen.Flags=OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&lopen)==TRUE)
ShowMessage((String)lopen.lpstrFile);

Окно Свойств файла или папки

4 Если щелкнуть правой кнопкой мышки по папке или файлу в "Проводнике" и выбрать в появившемся контекстном меню пункт "Свойства (Properties)", то мы увидим следующее окно (рис.4).

Научимся вызывать его программным путем. Для этого следует обратиться к функции ShellExecuteEx и структуре SHELLEXECUTEINFO. И, как это ни покажется утомительным, снова создать экземпляр структуры, проинициализировать его члены и передать по ссылке в функцию.

Ниже приведен код, реализующий эти действия:

SHELLEXECUTEINFO sh;
ZeroMemory(&sh,sizeof(sh));
sh.cbSize=sizeof(sh);
sh.lpFile="c:\\Windows";
sh.lpVerb="properties";
sh.fMask=SEE_MASK_INVOKEIDLIST;
ShellExecuteEx(&sh);

Окна удаления, копирования и перемещения

Рассмотрим еще один тип окон, которые полезны в случае, когда вы предусмотрели возможность производить из своей программы удаление, копирование или перемещение файлов.

Такой файловый менеджер "всех времен и народов", как Windows Commander, предлагает пользователю в течение обозначенных выше операций полюбоваться происходящим процессом, тот же "Проводник" в этих случаях не упускает возможность лишний раз поместить на экран монитора очередное окно, да к тому же с анимацией. А это, в свою очередь, создает иллюзию подконтрольности ситуации, что не напрягает.

Согласитесь, это выглядит намного солиднее, чем просто замена курсора мышки на вращающиеся песочные часы!

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

SHFILEOPSTRUCT fop;
ZeroMemory(&fop,sizeof(SHFILEOPSTRUCT));
fop.hwnd=Handle;
fop.wFunc= FO_COPY; // FO_DELETE- для удаления , FO_MOVE - для перемещения
fop.pFrom="C:\\Test.dat\0\0";
fop.pTo="D:\\Test.dat"; // в случае удаления этот член игнорируется
fop.fFlags=FOF_SIMPLEPROGRESS | FOF_ALLOWUNDO;
fop.lpszProgressTitle="I'm copying this file"; // фраза, соответствующая производимой //операции
SHFileOperation(&fop);

На этом, пожалуй, ограничимся. Напоследок отметим три обстоятельства.

Частичный отказ от VCL-компонент и методов в вашей программе путем прямого обращения к API позволяет, в ряде случаев, получить выигрыш в скорости.

Как правило, прямое использование API снимает многие ограничения в функциональности, присущие VCL-компонентам и методам, и в то же время дает возможность лучше разобраться в самой библиотеке визуальных компонент.

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

Источник: "Компьютер Price", http://www.comprice.ru

 


Copyright © "Internet Zone", http://www.izcity.com/, info@izcity.com