Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > paramcount&paranstr()


Автор: The ded 19.10.2004, 17:13
В событии oncreate нужно сделать так, чтобы ВСЕ выделенные(ДО запуска программы) файлы добавились бы в listbox...Наверное нужно использовать paramcount&paranstr() в структуре типа
той, которую я использую в opendialog'e :
for i:=0 to opendialog1.files.count do
listbox1.items.add(opendialog1.items.strings(i))...

:offtopic Кстати, что это за свойство capacity такое?

Заранее спасибо!!! :sample

Автор: p0s0l 19.10.2004, 20:58
Цитата(The @ 19.10.2004, 17:13)
В событии oncreate нужно сделать так, чтобы ВСЕ выделенные(ДО запуска программы) файлы добавились бы в listbox...
А где они выделены ? В TotalCommander'е ?
Через ParamStr можно прочитать параметры, которые указывают при запуске твоей программы, типа:
yourprogram1.exe abc.dat img1.jpg img2.jpg
Тогда в твоей проге будет так:
ParamStr(1) = "abc.dat"
ParamStr(2) = "img1.jpg"
ParamStr(3) = "img2.jpg"
Чтобы добавить всё это в ListBox, делай так:
for i := 1 to ParamCount do ListBox1.Items.Add(ParamStr(i));

А про OpenDialog что-то я не понял...

Capacity - "вместимость", на сколько строк зарезервировано памяти. В принципе, этот параметр лучше не трогать, не зная, как им пользоваться. Он служит лишь для оптимизации.


Автор: The ded 19.10.2004, 21:13
Цитата
А где они выделены ? В TotalCommander'е ?

в проводнике...
Цитата
for i := 1 to ParamCount do ListBox1.Items.Add(ParamStr(i));

у меня почему-то не меняется paramcount(только 1 и не больше!(сколько бы я не выделял файлов))
Цитата
А про OpenDialog что-то я не понял...

А там тоже самое... :yasno

Автор: p0s0l 19.10.2004, 22:31
Цитата(The @ 19.10.2004, 21:13)
в проводнике...

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

Но если тебя это устраивает, то навскидку план будет таков:
1)Узнай вначале класс окна проводника
2)Ищи окно такого же класса при запуске программы. Если окон несколько - выбирай самое верхнее (в Z-порядке)
3)Ищи в нём окно класса ListView (скорее всего это)
4)Получив хэндл ListView, узнай, какие элементы в нём выделены.
ListView_GetCount - получить кол-во элементов
Делаешь цикл от 0 до полученного значения-1:
в цикле ListView_GetItem - получить итем
У каждого полученного итема проверяй поле state, и если бит LVIS_SELECTED включен, то итем - выбран, его текст в поле pszText

Ну если там другой класс (честно говоря, проводником никогда не пользовался :)) - то примерно такая же схема, только будут другие функции / или другие сообщения...

PS: если будут трудности или вопросы - говори, расскажем подробнее, а может даже дадим готовый пример...

Автор: The ded 20.10.2004, 22:06
Я только знаю ф-ю findwindow => по пункту 1) сразу вопрос...

Цитата
PS: если будут трудности или вопросы - говори, расскажем подробнее, а может даже дадим готовый пример...


хотелось бы..... :sample

Автор: p0s0l 20.10.2004, 23:29
Вот сделал пример - ListBox1 заполнится названиями выделенных элементов в самом верхнем открытом Проводнике (если я правильно понимаю, что такое Проводник :) - это обычное окно, типа "Мой компьютер" ?)
Если Проводник - это то окошко, где еще сбоку дерево каталогов, то тогда вместо класса CabinetWClass надо написать ExploreWClass:
Код
procedure TForm1.Button1Click(Sender: TObject);
var
 wnd, wndLV : HWND;
 buf : array [0..255] of char;
 ItemNo, ItemCount : integer;
 PID, tmp : DWORD;
 hProcess : THandle;
 Adr : pointer;
 Buffer : record
   li : TLVITEM;
   txt : array [0..4095] of char;
 end;

begin
 ListBox1.Items.Clear;

 wnd := FindWindow ('CabinetWClass', nil);
//  wnd := FindWindow ('ExploreWClass', nil);  // !!! ВОТ ОНА СТРОКА ЭТА !!!

 wndLV := FindWindowEx (wnd, 0, 'SHELLDLL_DefView', nil);
 wndLV := FindWindowEx (wndLV, 0, 'SysListView32', nil);
 ItemCount := ListView_GetItemCount (wndLV);

 GetWindowThreadProcessId (wndLV, PID);
 hProcess := OpenProcess (PROCESS_ALL_ACCESS, False, PID);
 Adr := VirtualAllocEx (hProcess, nil, SizeOf(Buffer), MEM_COMMIT, PAGE_READWRITE);

 FillChar (Buffer.li, SizeOf(Buffer.li), 0);
 Buffer.li.mask := LVIF_TEXT;
 Buffer.li.iSubItem := 0;
 Buffer.li.cchTextMax := SizeOf(Buffer.txt);
 Buffer.li.pszText := @Buffer.txt;
 Inc(DWORD(Buffer.li.pszText), DWORD(Adr) - DWORD(@Buffer));

 for ItemNo := 0 to ItemCount-1 do
   if ListView_GetItemState(wndLV, ItemNo, LVIS_SELECTED) <> 0 then
   begin
     Buffer.li.iItem := ItemNo;
     WriteProcessMemory (hProcess, Adr, @Buffer, SizeOf(Buffer), tmp);
     SendMessage (wndLV, LVM_GETITEM, 0, LongInt(Adr));
     ReadProcessMemory (hProcess, Adr, @Buffer, SizeOf(Buffer), tmp);
     ListBox1.Items.Add(Buffer.txt);
   end;

 VirtualFreeEx (hProcess, Adr, 0, MEM_RELEASE);
 CloseHandle (hProcess);
end;


PS: А можно универсальную сделать версию. Вместо тех двух строк напиши:
Код
 wnd := FindWindow ('CabinetWClass', nil);
 if wnd = 0 then wnd := FindWindow ('ExploreWClass', nil);

Если не найдёт одно, попытается найти другое

Автор: Akella 21.10.2004, 08:55
WinRar както работает же? :qstn

и даже при незапущенной прогремме

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

Цитата
(честно говоря, проводником никогда не пользовался )

довольно удобная вещь, начинаю с Win95 только им и работаю, иногда с фаром

Автор: p0s0l 21.10.2004, 11:04
Цитата(dsergey @ 21.10.2004, 08:55)
WinRar както работает же?
Это уже другой вопрос. Запустить из контекстного меню и запустить обычным макаром - вещи немного разные. Во втором случае никакой информации о выделенных файлах программе не передаётся.

Автор: The ded 31.10.2004, 13:40
Спасибо за беспокойство, но приведённый код не работает, т.е. ничего не происходит(listbox остаётся девственно чистым)!

TLVITEM находится в commctrl, не так ли?

for i := 1 to ParamCount do ListBox1.Items.Add(ParamStr(i)); начинает работать иногда после format ц: , но не всегда=)

Win9X

Автор: p0s0l 31.10.2004, 18:08
Видимо в Win9x окно проводника имеет другое название класса...
Посмотри сам...
Например, создай новый проект, в него добавь таймер, и на таймер повесь:
Код

procedure TForm1.Timer1Timer(Sender: TObject);
var
 Buf : array [0..255] of char;
 wnd : hwnd;
 lv : TLVItem;
 s, s1 : string;
begin
 s := '';
 wnd := WindowFromPoint (Mouse.CursorPos);
 while wnd <> 0 do
 begin
   GetClassName(wnd, @Buf, SizeOf(Buf));
   s1 := Buf;
   s := '"' + s1 + '"' + ' -> ' + s;
   Wnd := GetParent (wnd);
 end;
 Caption := s;
 Timer1.Interval := 1;
end;

Запусти проект, и наведи мышь проводник, в область ListView (там где иконки). В заголовке твоего окна должно появиться типа такого:
"CabinetWClass" -> "SHELLDLL_DefView" -> "SysListView32" ->
Если будет не так, то соответственно, подправь имена классов...
(можно сделать проверку версии винды и соответственно искат нужные названия классов)

Цитата(The @ 31.10.2004, 13:40)

TLVITEM находится в commctrl, не так ли?
Да...


Добавлено @ 18:11
Мдя... Щас пересмотрел свой код, и понял, что в 9x это не должно работать, т.к. используется функция VirtualAllocEx...
Как сделать без неё в Win9x - не знаю...
Цитата(MSDN)
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0.

Странно, что прога у тебя вообще запустилась на девятке... Должно было выскочить окошко, что-то типа "Функция VirtualAllocEx не найдена в Kernel32.dll"...

Автор: The ded 1.11.2004, 22:35
Нет всё работает =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)