Win32 вопросы

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

ALS wrote:Так, в порядке бреда - есть параметры LVSCW_AUTOSIZE и LVSCW_AUTOSIZE_USEHEADER. С ними не пробовали "поиграться" ?
Читаю про них вот как раз http://msdn.microsoft.com/ :
List-View Window Styles...

А константы, похоже - в CommCtrl.h

Но, видимо, я не то опять читаю! :-? Надо читать:
List-View Controls Messages
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Да, блин... "чукча - не писатель... чукча читатель"... :(

Нет таких констант, потому что их никто не придумал и никогда!

Читаем исходный совет от дельфийцев:
Вопрос: Как в ListView запретить вручную изменять ширину столбцов?
Ответ: можно так:

Code: Select all

ListView.Colimns[x].MaxWidth := yyy;
ListView.Colimns[x].MinWidth := yyy;
правда, пользователь сможет менять ширину, но после отпускания кнопки
мыши она вернется в прежний размер.
:o

Это то же самое, что я и предположил с самого начала:
Lavr wrote:...временно я сделал вот что - в конце процедуры обработки сообщений
от List View control я поставил восстановление размеров.
Но получилось несколько смешно: "дрыгающаяся таблица"...
Похоже, что самое верное решение пока предлжил b2m:
b2m wrote:есть один радикальный метод: перехват windowproc
Действительно подтверждается:"Сам по себе ListView весьма удобен и
многофункционален, но ... ширину его колонок невозможно зафиксировать.
То есть пользователь всегда будет волен изменять их, как его душе угодно...
...переопределим WndProc() для самого ListView...
"



PS. Попался ещё один "Дельфийский" метод:
Подскажите, каким образом возможно запретить ресайз колонки в ListView
(режим vsReport). Выставление значений MaxWidth и MinWidth в принципе
решают проблему, но наполовину: ресайз делать можно, но когда отпускаешь
кнопку мыши, размер возвращается в первоначальный. А надо так, чтобы даже
тянуть нельзя было.

Code: Select all

procedure TForm1.FormCreate(Sender: TObject); 
var Header: HWND; 
begin 
Header := FindWindowEx(ListView1.Handle, 0, "SysHeader32", nil); 
if (Header <> 0) then EnableWindow(Header, false); 
end;
Это работает, ... на весь ListView...[/size]
iLavr
b2m
Devil
Posts: 905
Joined: 26 May 2003 06:57

Post by b2m »

ALS wrote:Так, в порядке бреда - есть параметры LVSCW_AUTOSIZE и LVSCW_AUTOSIZE_USEHEADER. С ними не пробовали "поиграться" ?
В порядке бреда, отвечаю: этим ты можешь лишь единовременно установить ширину по содержимому колонок (второе - включая текст заголовка колонки), но это никак не повлияет на поведение заголовка.
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/
User avatar
ALS
Senior
Posts: 123
Joined: 07 Aug 2012 11:11
Location: Севастополь

Post by ALS »

Мне можно было не отвечать, я в этих ф-циях вообще не разбираюсь Image
А вот как выглядит прога на делфи - link
Ширину колонок можно пытаться менять, но никакого "дрыганья" там нет.
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

ALS wrote:Ширину колонок можно пытаться менять, но никакого "дрыганья" там нет.
У меня вобщем-то также... "Дрыганье" - термин довольно условный... :lol:
Я имел ввиду, что тащишь мышью маркер сдвига столбца - а он как бы назад
отлетает, когда кнопку отпустишь...

Да можно и остановиться на этом... но не люблю полумеры. Сейчас пробую
вот этот трюк:

Code: Select all

var Header: HWND; 
begin 
Header := FindWindowEx(ListView1.Handle, 0, "SysHeader32", nil); 
if (Header <> 0) then EnableWindow(Header, false); 
end;
Он должен сработать, но, боюсь, другая проблема может возникнуть - таблица
не сможет реагировать на тултипы...
Функция EnableWindow включает или отключает мышь и ввод с клавиатуры в определенном окне или элементе управления. Когда ввод заблокирован, окно не принимает ввод типа щелчков мыши и нажатий клавиш.
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Фиксация колонок элемента ListView

Post by Lavr »

Фиксация колонок элемента ListView

Code: Select all

var Header: HWND; 
begin 
Header := FindWindowEx(ListView1.Handle, 0, "SysHeader32", nil); 
if (Header <> 0) then EnableWindow(Header, false); 
end;
Совет действует безотказно и пока без замечаний!!! :D

Только при переходе в WIN32 я затупил, так что промучался часа 4... :(

И вся ерунда заключается в том, что в вызове:
FindWindowEx(ListView1.Handle, 0, "SysHeader32", nil);
ListView1.Handle - это хэндлер заголовка таблцы элемента ListView

Image

Как видно из рисунка, если мы размещаем ListView control на форме, то форма
является для него
parent.
И ListView control является окном класса "SysListView32" без заголовка.

А вот Header ListView control-a является окном класса "SysHeader32" без заголовка,
и для него уже сам ListView - parent.

Таким образом, если хэндлер ListView control неизвестен, то проблема решается
в три строчки:

Code: Select all

             hWParent=FindWindowExA(WinMain,0,"SysListView32",null)
             ListHead=FindWindowExA(hWParent,0,"SysHeader32",null)
             EnableWindow(ListHead,FALSE)
А я затупил и искал Header как дочернее окно WinMain... :-?
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Re: Win32 вопросы

Post by Lavr »

Lavr wrote:Я тут, работая над 4bit CPU, при каждом изменении схемы вынужден вручную
редактировать вот такую таблицу:

Image

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

----Image

Но на тестах выяснилась одна непрятная особенность работы этого
контрола ListView - в него весьма медленно загружаются сравнительно
крупные файлы.
В сети приводят статистику, что на довольно шустрых машинах 60.000
записей грузятся более минуты.
Но у меня получается, что на 1 запись происходит вставка 20 позиций
в сетку ListView, что довольно-таки долго уже при размере файла порядка
17-20 КБайт.

Нашел в сети только один совет, якобы ускоряющий загрузку: на время
загрузки отключить у ListView - контрола отображение на морде, потому
как якобы ListView - контрол весьма умный и много всяких собственных
вычислений делает во время вставки в него элементов, причем чем больше
объём элементов, тем тормознее всё становится.

Но совет был на Дельфи, а у них все Вендовые контролы в свою "обёртку"
упрятаны и блокировку выставляют по типу "ListView.свойство".
У меня же через вызовы WIN32API практически всё реализовано и что-то я
никак не сображу как этот совет реализововать.
Хотя и там обещают прирост скорости лишь на 25-30%.

Или может не морочить себе мозг - всё же это инструмент специфичный, а
не универсальный. Может и не надо редактировать ПЗУ микрокоманд размером
более 16КБайт?

Так-то по всем остальным параметрам этот Едит довольно шустр...


PS. И еще при загруженном крупном файле Едит при выключении "задумывается"...
память ListView - контрола освобождает что-ли...
:-?
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Попробовал реализовать эту идею вот как:

Code: Select all

             hWParent=FindWindowExA(WinMain,0,"SysListView32",null) 
             EnableWindow(hWParent,FALSE)
То есть по хэндлеру ListView-контрола сделал его самого "Disable" на время загрузки файла.

ListView-контрол становится серым и без сетки, но продолжает, зараза вычислять размеры
своей боковой полосы прокрутки и менять её размер в зависимости от объёма уже загруженных
в ListView-контрол байт.

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

Я вот думаю - может быть на время загрузки файла сделать ListView-контрол "hide" - убрать
его с формы?
Или он и невидимый будет расчеты своей геометрии делать... :-?



PS. Оригинальный совет в принципе выглядит вот так:

Code: Select all

    lv.lockWindowUpdate(true); 

    for (i=1; i<=30000; i++) 
       lv.addItem(new FormListItem('test' + int2str(i))); 

    lv.lockWindowUpdate(false);
Но я не знаю, как сделать это через WIN32API - мне надо для этого послать контролу какой-то мессаг...

PPS. Это, оказывается, вот как делается в WIN32API:

Code: Select all

             hWParent=FindWindowExA(WinMain,0,"SysListView32",null) 
             LockWindowUpdate(hWParent,)
...
             LockWindowUpdate(0)
Действительно, эта функция полностью подавляет отрисовку одного окна...
Но феноменального ускорения не заметил, хотя несколько быстрее загрузка идет.
iLavr
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Lavr wrote: Это, оказывается, вот как делается в WIN32API:

Code: Select all

             hWParent=FindWindowExA(WinMain,0,"SysListView32",null) 
             LockWindowUpdate(hWParent,)
...
             LockWindowUpdate(0)
Действительно, эта функция полностью подавляет отрисовку одного окна...
Но феноменального ускорения не заметил, хотя несколько быстрее загрузка идет.
В общем - остановился я на этом варианте. Потому как понял, что быстрее, пожалуй, не будет.

Всё-таки, если программа побитно обрабатывает, к примеру, 15.000 байт - на это нужно время,
даже если нет обращения к диску.

Попробовал опцию "загрузки" без обращения к дисковому буферу - просто возвращал принудительно
байт 00Н - для 15.000 позиций время всё-равно реально требуется, на быстром компьютере - конечно
же всё будет быстрее.

Даже простая перестановка бит LSB ---> MSB всё-равно не быстрая при 15.000 позициях в сетке. :lol:
iLavr
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Post by DimkaM »

А если изымать листвью из контролсов формы?!
хз как на сях, на сишарпе
this.Controls.Remove(myListView);
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

DimkaM wrote:А если изымать листвью из контролсов формы?!
хз как на сях, на сишарпе
this.Controls.Remove(myListView);
И что это даст? То есть, я изыму "листвью из контролсов формы" и в это же время буду заполнять
его "айтемы" и "сабайтемы"?
Мне надо чтобы от лишней ерундой не занимался во время загрузки и не тормозил, ну он теперь
практически и не занимается. Может быть втихаря - но это ему запретить нельзя... :wink:
Как-никак его память заполняем, а он к разным разностям должен быть готов.
iLavr
aav8
Maniac
Posts: 287
Joined: 05 Nov 2008 19:47
Location: 81.28.208.238

Post by aav8 »

Я когда рисовал HEX редактор, со стандартными
контролами не стал заморачиваться, и все нарисовал
заново на чистом API/GDI
User avatar
Lavr
Supreme God
Posts: 16676
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

В старые бородатые времена, когда я не знал про такой контрол, а может его и не было ещё,
я тоже, помню, написал похожий контрол сам:

Image

А сбоку вон и скроллер написал сам... :wink: Не потому что про скрoллеры не знал, а потому что
от стандартного скроллера почему-то не получал ответа. :lol:

Но в этот раз решил использовать ListView - контрол, и отступать уже некуда, всё уже
практически написано! 8)
iLavr
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Post by DimkaM »

Lavr wrote:И что это даст? То есть, я изыму "листвью из контролсов формы" и в это же время буду заполнять
его "айтемы" и "сабайтемы"?
Заполнишь, потом добавишь обратно в контролсы. А пока его не будет в контролсах - он не будет рефрешица
DimkaM
Maniac
Posts: 261
Joined: 22 Jun 2005 04:35
Location: МО Россия

Post by DimkaM »

я для вывода sql запросов юзаю DataGridView.
В твоём случае можно заранее создать DataTable(и тп), заполнить и подцепить к DataGridView

но это уже фреймворк нада 3.5