IPB

Добро пожаловать, гость ( Вход | Регистрация )

9 Страниц V « < 2 3 4 5 6 > »   
Reply to this topicStart new topic
> Delphi, Asm, C, WinAPI, PHP, ..., FAQ
-=CHE@TER=-
Nov 11 2011, 15:15
Сообщение #61


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



У Delphi такой смешной оптимизатор (компилирую программу через DCC32HACK - там глюки и косяки сразу хорошо видно, т.к. программа маленькая и без мусора):

CODE
Const Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

Делает копию этой строки в каждом (!) месте программы где она используется.

Если же написать так:
CODE
Const Chars: String = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

То только в первом - все остальные на неё ссылаются.

А вот так:
CODE
Const Chars: String[36] = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

Вообще загоняет строку отдельно в секцию DATA.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Nov 11 2011, 15:25
Сообщение #62


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Как я понимаю при конкатенации (дурацкое слово) строк создаётся новый элемент типа string, и если потерять указатели на строки из которых складывалась новая, т.е. например S:=S+S, или добавлять вручную значение, например S:=S+'s', то будет утечка памяти? Хочу вспомнить как правильно и не громоздко работать на строками на D7, а то работа на Java расслабляет...
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Nov 11 2011, 20:39
Сообщение #63


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Похоже долго ты на Java писал. (*улыбается*)

Нет, насколько я помню, Delphi хранит указатели на сложные типы данных и количество переменных ссылающихся на них. Как только количество = 0, то переменная уничтожается. Если же ты делаешь T:=S;, то у тебя в T не хранится строка S, а только указатель на неё. Реально память выделяется, если я правильно помню, только когда ты начинаешь изменять T, например: T:=T + 's';
Уже не помню, где об этом читал, где-то статья была, может даже здесь (на форуме) ссылку давали.
О, нашёл - там нет якорей, так что крути вниз до главы "Как же это происходит?".
Так это происходит или нет, судить не берусь, но, вроде бы, в этой главе походит на правду.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Nov 14 2011, 13:41
Сообщение #64


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Siberian GRemlin!

До меня, кажется, дошло, почему ты спросил. (*улыбается*)

QUOTE(-=CHE@TER=- @ Nov 11 2011, 15:15) *
CODE
Const Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

Делает копию этой строки в каждом (!) месте программы где она используется.

Это моё замечание (как и другие из того сообщения) относились не к динамическому размещению строк в памяти во время работы программы, а к размещению данных в .EXE файле. Т.е. в приведённом случае в .EXE файле на диске будет три раза продублированна в разных местах эта строка. Таким образом, к примеру, в случае большого массива, размером, предположим в 64 Кб (скажем, для расшифровывания чего-нибудь) на диске такое безобразие будет занимать 64*3 Кб + код программы, где 3 - количество обращений к этому массиву (в данном случае у меня их было 3).
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jan 14 2012, 13:26
Сообщение #65


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Писал я недавно патч для включения крови в German версии Turok 2. Решил, чтобы не маяться с CreateWindow(), сделать диалог в ресурсах. Взял из FASM пример EXAMPLES\DIALOG\DIALOG.ASM и переколбасил его под свои нужды. Всё работает, но странности начались, когда я решил навести последний штрих - добавить manifest для XP/Vista/7.
Программа стала сразу выходить после запуска. Офигев от такого безобразия начал отлаживать - выяснилось, что DialogBoxParam() сразу выходит даже не отображая окно. Убираем манифест - всё снова работает. Пошёл гуглить и натолкнулся вот на такую статью:
Особенность InitCommonControlsEx в Windows XP
(кстати, там на сайте и другие статьи интересные есть - их немного, так что пробегитесь по ним, кому интересно)
В общем, суть такова: чтобы программы с манифестом и DialogBoxParam() работали как надо, нужно чтобы в импорте была библиотека COMCTL32.DLL. Это можно сделать, вызвав, к примеру, InitCommonControls(). Я решил её не вызывать (толку-то всё равно не будет), а просто перепрыгнуть:
CODE
jmp @ICC
invoke InitCommonControls
@ICC:

Мне главное, чтобы в импорте COMCTL32.DLL была, а если ни одна функция оттуда не вызывается, то компилятор удаляет её из импорта.
Вот такая фигня.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Mar 7 2012, 20:37
Сообщение #66


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



QUOTE(-=CHE@TER=- @ Aug 10 2010, 14:27) *
Вчерась ковырял одну игрушку, где данные были упакованы deflate. Как и всегда использовал puff.c + puff.h из zlib. Внезапно, при распаковке, получаю ошибку записи в память по адресу 0, программа падает. <...>
Наконец-то обновили - забираем.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Mar 12 2012, 09:13
Сообщение #67


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



QUOTE(-=CHE@TER=- @ Nov 11 2011, 15:15) *
У Delphi такой смешной оптимизатор (компилирую программу через DCC32HACK - там глюки и косяки сразу хорошо видно, т.к. программа маленькая и без мусора):
Кто-нибудь знает, как можно сразу, без этих приседаний, загонять константы в секцию .DATA? Может переключатель {$..} какой есть? А то Delphi их дублирует, скотина, в .CODE размещать не хочу, а для каждой строки писать String[кол-во_символов] = '...'; очень нудно.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Mar 12 2012, 11:07
Сообщение #68


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



QUOTE(-=CHE@TER=- @ Mar 12 2012, 17:13) *
для каждой строки писать String[кол-во_символов] = '...'; очень нудно.
Я для InnoSetup писал прогу в которой вставляешь строки, а она выдаёт код с массивом строковых констант. Возможно и тебе это будет проще делать.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Mar 24 2012, 09:13
Сообщение #69


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Кто-нибудь знает где можно взять готовый код под PHP4 для генерации картинки с текстом? Наподобие того как это сделано для телефона продавца на сайте avito.ru - нужно открыть какое-нибудь объявление и там будет "показать телефон продавца". Пробовал разные запросы, но поисковик выдаёт сайты на которых можно ввести текст, выбрать шрифт и пр. и он выдаст какую-нибудь красивую картинку.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Mar 24 2012, 11:58
Сообщение #70


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Вот тут (за номером 7 самый простой, и ниже - до конца, уже сложнее) натыкался когда-то на генератор на PHP, который добавляет текст на изображение. Посмотри что да как, лишнее выкини. Все эти функции описаны в справке по PHP. Если я не ошибаюсь это расширение GD2 Lib, которое на современных серверах должно быть.
Если же у тебя вообще голый PHP без расширений, то можно самому сгенерировать и выводить .BMP файл, правда занимать он будет больше (впрочем, можно немного поприседать и сделать ч/б, чтобы меньше весил).


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 14 2012, 15:39
Сообщение #71


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



В Си есть такая замечательная функция, как sprintf(), которая позволяет формировать строчку со всякими '%s', '%03d' и прочим. Эта функция есть в msvcrt.dll, однако, я не люблю эту библиотеку, так как на чистой Windows 98 SE у меня её не было - она ставится только с какой-нибудь программой, да и вообще, в ядро системы не входит.

Зато в ядро системы входит wsprintf(). К сожалению, в Delphi она криво объявлена, в результате чего ей нельзя пользоваться. Как мы помним, у всех таких функций может быть разное количество аргументов - это, оказывается, решается ключевым словом "varargs":

CODE
function wsprintf2(Output: PChar; Format: PChar): Integer; cdecl; varargs; external 'user32.dll' name {$IFDEF UNICODE}'wsprintfW'{$ELSE}'wsprintfA'{$ENDIF};

Вот такое объявление (я его уже не помню где нашёл в Интернете) - работает.
cdecl, как мы помним, говорит о том, что в отличие от stdcall, вызываемая функция не знает сколько параметров сложено на стек, так что об их снятии со стека после работы функции должна позаботиться вызывающая сторона, что в данном случае логично.

Нужно только помнить пару вещей:
1) В MSDN настоятельно не рекомендуют пользоваться этой функцией (небезопасна, если криво используется), но в Windows 7 и ниже она есть (в Windows 98 есть только wsprintfA).
2) В этой функции ограничение на 1025 байт для ANSI и 1025*2 для UNICODE буфера - т.е. если строчка больше, то она просто будет отрезана.
3) Она поддерживает далеко не все возможности, которые есть в sprintf (кажется, с дробными числами не работает - см. MSDN).

Пример использования (S - переменная типа String):
CODE
// максимальный размер буфера
SetLength(S, 1025);
// отрезаем по границе - сколько реально было использовано
SetLength(S, wsprintf2(PChar(S), '%03d - %s', 45, PChar('Hello World!')));


P.S. Да, в Delphi есть FmtStr(), но она подключается вместе с SysUtils и ещё кучей мусора, что для небольших программ на WinAPI просто неприемлемо.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 15 2012, 10:32
Сообщение #72


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



И ещё о нескольких устаревших (по мнению MSDN, где ими не советуют пользоваться) функциях.

Часто программе нужно где-то хранить настройки. Вариантов хранения два:
1) В файле.
2) В реестре.

Microsoft настоятельно рекомендует пункт 2 и пользоваться для этих целей веткой реестра HKEY_CURRENT_USER \ Software, чтобы у каждого пользователя были свои настройки - т.е. каждый вошедший в систему пользователь мог настроить программу "под себя" (так как ему нравится). Как известно HKEY_CURRENT_USER загружается автоматически вместе с текущим профилем пользователя при входе в систему и у каждого пользователя эта ветка реестра будет своя (разумеется, кроме тех одинаковых вещей, которые по умолчанию добавляет туда сама система при создании профиля для нового пользователя). К слову, HKEY_LOCAL_MACHINE - это глобальная ветка, настройки в которой доступны всем пользователям (вернее будет сказать, что это настройки для всего компьютера), посему и писать туда не имея прав администратора вообще нельзя.

Хранение же настроек в файле чревато тем, что у всех пользователей будут одни и те же настройки, а если каждый захочет менять под себя... будет мало хорошего. В принципе, можно хранить настройки в каталоге пользователя C:\Documents and Settings\USERNAME\Application Data\<ИМЯ ПРОГРАММЫ> (т.н. каталог %APPDATA% - который, как и ветка реестра, у каждого пользователя свой).

Однако, и реестр и каталог пользователя "болеют" одной проблемой: при удалении программы, все эти вещи остаются. Т.е. система получается загажена неиспользуемыми данными - "мусором". Можно, конечно, сделать установщик, который будет все эти вещи чистить при удалении программы.
Однако же:
1) Надо писать установщик.
2) Надо писать логику и обработку удаления программы.
3) Программа перестаёт быть portable (портативной - переносной, ей обязательно нужен будет доступ для записи либо в реестр, либо на жёсткий диск).
Самый серьёзный пункт - это пункт 3.
Но даже не в этом дело, а в том, что многие пользователи до сих пор, "по привычке", удаляют программу через SHIFT+DELETE, вместо "Установки и удаления", что сводит все старания из п.п. 1 и 2 на нет.
Наконец, для программ, которые являются каким-то разовыми утилитами и которыми не пользуешься каждый день, все эти вещи просто лишние.

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

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

Уф, ладно, со вступлением закончил. (*улыбается*)

Теперь переходим к практике. Для работы с .INI файлами есть в WinAPI следующие функции:
GetPrivateProfile* - для чтения
WritePrivateProfile* - для записи
* - означает, что есть несколько функций, которые начинаются на эту строку, но имеют разные окончания.

Для примера рассмотрим вот такой тестовый "test.ini" файл:
CODE
[Main]
Param1=123
StrVal=String!

Для того, чтобы прочитать оттуда нужно сделать следующее:
CODE

Var
  S: String;
  X: Integer;
Begin
...
// максимальный размер строки - 100 символов
SetLength(S, 100);
// меняем на тот, сколько реально было прочитано
SetLength(S, GetPrivateProfileString('Main', 'StrVal', '', @S[1], Length(S), '.\test.ini'));
X:=GetPrivateProfileInt('Main', 'Param1', 0, '.\test.ini');

Ну и писать, точно также, только через WritePrivateProfile*.
Кстати, чтобы удалить из .INI достаточно написать (Nil - в качестве значения параметра, чтобы удалить):
CODE
WritePrivateProfileString('Main', 'StrVal', Nil, '.\test.ini');

И StrVal вообще исчезнет из .INI файла.

Важные замечания:
1) Не путайте (Get/Write)PrivateProfile* и просто (Get/Write)Profile* - последние функции (без Private в названии) пишут в системный файл "WIN.INI"! А его лучше не трогать, к тому же доступа на запись в системный каталог может не быть.
2) Не забывайте писать '.\' в начале имени файла. Это важно - если написать просто 'test.ini', то этот файл будет сохранён в "C:\Windows\test.ini" - а прав записи туда может не быть.
3) Функций гораздо больше (не только *String и *Int) - см. справку по MSDN. Я, кстати, здесь не объяснил некоторые параметры (значения по умолчанию, например, если параметра в файле нет) - за всем этим, а также другими удобными вещами и прочими тонкостями - см. MSDN.
4) Как я уже говорил, MSDN настоятельно рекомендует не пользоваться этими функциями и посылает всех в реестр, однако же, они вполне себе спокойно работают и под Windows 7.

P.S. В Delphi есть IniFiles при подключении которого через uses появится класс TIniFile работающий с .INI файлами и независящий от перечисленных WinAPI функций, однако же, как я уже писал в сообщении выше, для небольших программ на WinAPI подключение этого модуля чудовищно раздувает размер кода.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 19 2012, 13:23
Сообщение #73


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Проводя очередную чистку системы, натолкнулся на файл:
C:\WINDOWS\Perflib_Perfdata_*.dat
который не хотел удаляться. Внутри была видна как-то информация от долбанного .NET.
Unlocker показал, что этот файл "держит" процесс G6FTPServer.exe (Gene6 FTP Server 3.8.0.34).
Как выяснилось, это система чего-то пишет, при запросе статистики об используемой памяти, процессорного времени и т.д.
Отключается сиё безобразие переименованием или удалением файла:
C:\Program Files\Gene6 FTP Server\Plugins\g6_log_system.dll
Не забудьте перед этим остановить службу FTP-сервера, а потом снова включить.
Там оно ещё и в реестр постоянно лезет из-за этого.
В результате отключения этой .DLL информации о загрузке системы в логах не будет, но мне она и так никуда нафиг не упёрлась.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Grom PE
Apr 19 2012, 19:05
Сообщение #74


Advanced Member
***

Группа: CTPAX-X
Сообщений: 84
Регистрация: 7-February 08
Из: i@grompe.org.ru
Пользователь №: 3,120
Спасибо сказали: 95 раз(а)



Сам у себя встречал такие файлы. Полюбопытствовал, что и как.
Выяснилось, что можно взять и применить регу:
CODE
REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib]
"Disable Performance Counters"=dword:00000001
Тогда ни одна программа не будет создавать эти файлы.
А последствия - монитор производительности системы ничего не будет показывать.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 24 2012, 12:14
Сообщение #75


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



В очередной раз зайдя на сайт товарища Siberian GRemlin'а и увидев надпись (да, я таки поставил себе NoScript):
QUOTE
Для отображения ссылок необходимо разрешить выполнение 'JavaScript' в вашем обозревателе!
гласящую, что без JS на сайте ничего нельзя увидеть, я всё же решился дать ему ссылку тут на полезную статью, о том, как AJAX'ом пользоваться не надо: Блеск и нищета Ajax (хотя бы со слов: "Вот, пожалуй, и все об этом. А теперь тех, кто не уснул за чтением первой части статьи..." и далее), если, конечно, никакая индексация в поисковых системах (т.е. попытка спрятать сайт от поисковых роботов) не является частью какого-нибудь Хитрого Плана™. (*улыбается*)
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Apr 24 2012, 13:16
Сообщение #76


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Я так понимаю, ты знаешь способ создания динамичных страниц на голом HTML. Никого AJAX'а, кстати, тоже нет.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 24 2012, 15:37
Сообщение #77


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



QUOTE(Siberian GRemlin @ Apr 24 2012, 13:16) *
Я так понимаю, ты знаешь способ создания динамичных страниц на голом HTML. Никого AJAX'а, кстати, тоже нет.
AJAX = Asynchronous Javascript and XML (асинхронный JavaScript и XML).
Ну, у тебя там нет XML, а ты просто кусок сайта через массивы подгружаешь - в принципе, тоже какой-то вариант хранения данных.

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

Это всё к чему: у тебя хостер PHP или какие-либо другие серверные языки не разрешает использовать? Только голый HTML? У тебя же, вроде бы, собственный домен? Просто тогда можно было бы нормально генерить страницы на стороне сервера.

Если же только голый HTML, то это жесть, честно говоря.

Есть один способ - как я на народе выкручивался: делал шаблон сайта и парсер. Парсер выдирал контент (содержимое) из *.HTM файлов рекурсивно обходя все каталоги сайта. То что считалось за тело (т.е. не шапка, не подвал и не меню) помечалось как:
CODE
<!-- Content -->
тут тело документа
<!-- /Content -->

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

Но, видишь что, у меня списков постоянно меняющихся нет, я там, в основном, статьи пишу и ручками всё правлю. Тебе, возможно, будет проще сделать БД, где хранить списки игр и при компиляции сайта вставлять в нужное место. Скажем в документе пишешь %%GAMELIST_RU%%, а уже при компиляции заменяешь это слово на список нужных игр. Тебе тогда нужно будет делать несколько шаблонов: один общий для сайта (шапка, меню, подвал), а другой для каждой страницы, ну и готовые странички в отдельный каталог складывать. Можно даже перезаписывать только те, которые изменились, чтобы по дате отсортировать и на сервер только новые закидывать.

Вот такие варианты могу предположить.
Это не наезд, просто у тебя столько работы пропадает, потому что никак не индексируется - вот что грустно.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Apr 24 2012, 15:49
Сообщение #78


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Месяц назад я только договорился с админом и мне включили PHP, жаль только что 4-ой версии, а не 5-ой. Пока не было времени код переписать. Планирую сделать PHP+XML. Если есть идеи, то готов выслушать.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 24 2012, 16:19
Сообщение #79


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



О, блин, 4-ый PHP это уже здорово, чем вообще ничего!
Я не знал об этом, поэтому и предложил вот это всё.
Думаю с PHP у тебя уже проблем не будет.
Предложить особо нечего - если MySQL или какой-либо БД нет, то тогда действительно только в .XML хранить БД и парсить её при генерации страниц сайта на PHP.
simplexml_load_file(), к сожалению, только в PHP 5 появилась, смотри в сторону xml_parser_create() и других функций - они, судя по руководству к PHP, есть и в 4-ой версии.
Вот годная статья: XML и PHP, парсинг для чайников.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
May 30 2012, 10:22
Сообщение #80


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Нашёл в Delphi 7 охрененный косяк, который вынес мне мозг.

1) Создаём новую программу - пустую форму и вешаем обработчик на событие OnActivate (нам нужно показать окно с некоторой заполненной информацией в ListBox).
2) Кидаем на форму ListBox и вешаем обработчик на событие OnClick.
3) Пишем туда такой код:

CODE
procedure TForm1.ListBox1Click(Sender: TObject);
begin
  // if Sorted changed in FormActivate you'll see this only with keyboard
  ShowMessage('OnClick');
end;

procedure TForm1.FormActivate(Sender: TObject);
var i: integer;
begin
  for i:=1 to 10 do ListBox1.Items.Add(IntToStr(i));
  ListBox1.Sorted:=True // <-- bye-bye OnClick, DblClick and mouse events!
end;

4) Долбанный стыд - при изменении Sorted (неважно в True или False) внутри OnActivate - OnClick, OnDblClick у ListBox и все прочие события с мышки перестают обрабатываться. Работает только клавиатура...
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

9 Страниц V « < 2 3 4 5 6 > » 
Reply to this topicStart new topic
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 28th March 2024 - 12:54