Sign in Join
Wiki copytemporary

Win32/64 Interface/ru: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Win32/64 Interface/ru

OldNewLine
1+*(Windows only)*
2+
3+## Введение
4+
5+Интерфейс win32 / 64 является, пожалуй, самым отлаженным и хорошо разработанным интерфейсом Lazarus, а также наиболее часто используемым, учитывая количество загрузок. Несмотря на то, что он наиболее полный, есть некоторые проблемы, которые нуждаются в исправлении.
6+
7+Еще один важный момент, связанный с интерфейсом win32/64, заключается в том, что он в настоящее время находится в процессе [[LCL Unicode Support|миграции на unicode]].
8+
9+Win64: см. предостережение [[Windows Programming Tips|здесь]] о неиспользовании определенных версий FPC/Lazarus Win64.
10+
11+## Актуальные вопросы
12+
13+### Скроллинг
14+
15+В настоящее время прокрутка выполняется путем перемещения дочерних элементов управления вместо перемещения клиентской области, как ожидает LCL. Например, в некоторых случаях это выглядит так, как будто дочерние элементы прокручиваются в обратном порядке. Правда такова, что прокрутка в значительной степени сломана. Прокрутка дочерних элементов управления несовместима с другими наборами виджетов, а также имеет такой недостаток: перемещение одного дочернего элемента за другим генерирует несколько сообщений перемещения. LCL получает сообщения и должен реагировать каждый раз (например, он должен перераспределить все привязанные дочерние элементы). Для одного набора виджетов вы можете попытаться преодолеть эту проблему, но решение никогда не будет работать одинаково хорошо для всех других наборов виджетов. Этот подход работает для VCL Delphi, но не для LCL. Поэтому должен быть реализован другой подход:
16+
17+**Решение**
18+
19+Решением было бы вставить окно «клиентской области» между окном каждого дочернего элемента и его родительским окном. Дочерние окна помещаются в окно «клиентской области», и когда прокручиваются дочерние окна, вместо этого перемещается окно «клиентской области». Это уже сделано другими наборами виджетов.
20+
21+Замечание Mattias: В конце концов, я это реализую, но мои знания интерфейса winapi ограничены, и у меня уже есть множество других задач Lazarus, поэтому я не могу сказать, когда я это сделаю.
22+
23+**Связанные сообщения об ошибках**
24+
25+- [10400](http://bugs.freepascal.org/view.php?id=10400)
26+- [10188](http://bugs.freepascal.org/view.php?id=10188)
27+- [10471](http://bugs.freepascal.org/view.php?id=10471)
28+- [10091](http://bugs.freepascal.org/view.php?id=10091)
29+
30+### Показ рамки фокуса элементов управления, отображающихся в соответствии с темой
31+
32+Элементы управления (CheckBox, Button, TRadioButton и т.д.) теряют рамку фокуса, когда приложение использует темы.
33+
34+**Советы по решению**
35+
36+- По словам Пола, это не связано с WM_PAINT
37+
38+**Связанные сообщения об ошибках**
39+
40+- <http://bugs.freepascal.org/view.php?id=10685>
41+
42+### Навигация по элементам управления с помощью клавиш со стрелками
43+
44+**Связанные сообщения об ошибках**
45+
46+- <http://bugs.freepascal.org/view.php?id=10742>
47+
48+## Детали реализации
49+
50+Этот список объясняет, как определенные части LCL реализованы в интерфейсе Win32, чтобы помочь людям найти соответствующий код для исправления ошибок.
51+
52+### Цвет фона стандартных элементов управления
53+
54+См. также: [[Windows CE Development Notes|Windows_CE_Development_Notes#TRadioButton_and_TGroupBox]]
55+
56+Можно заметить, что в Windows нет реализации для TWSWin32WinControl.SetColor, а также для большинства стандартных элементов управления (GroupBox, RadioButton, CheckBox и т.д.), даже если эти элементы управления могут изменить свой цвет фона.
57+
58+Причина в том, что это реализовано обработкой сообщения WM_CTLCOLOR*. Большинство стандартных элементов управления (GroupBox, RadioButton, CheckBox и т.д.) посылают сообщение WM_CTLCOLORSTATIC. В этом сообщении можно установить цвет фона, и должен быть возвращен дескриптор кисти, используемой для рисования элемента управления.
59+
60+Еще одна важная деталь - это то, что дочерние элементы управления посылают свои сообщения WindowProc своего родителя. Итак, если у вас есть Форма с GroupBox и несколькими CheckBoxes внутри GroupBox, сообщения GroupBox будут отправляться в Form, а сообщения CheckBoxes будут отправляться в GroupBox (включая сообщение WM_CTLCOLORSTATIC). Чтобы преодолеть это, набор виджетов win32 использует SetWindowLong для сброса WindowProc элементов управления с дочерними элементами в наш централизованный WindowControl на win32callback.inc.
61+
62+### TCheckListBox
63+
64+См. также: [[Windows CE Development Notes|Windows_CE_Development_Notes#TCheckListBox]]
65+
66+- *TWin32WSCustomCheckListBox* реализует некоторые минимальные методы
67+- *TWin32WSCustomListBox* реализует создание дескрипторов и большинство методов
68+- *TWin32CheckListBoxStrings* является основным потомком TStrings для этого класса
69+
70+В Windows TCheckListBox является обычным окном класса 'LISTBOX', в котором установлен стиль LBS_OWNERDRAWFIXED. Когда будет создан список, будет отправлено сообщение WM_MEASUREITEM, а после, сообщение WM_DRAWITEM будет отправляться всякий раз, когда элемент должен быть отрисован. В обработчике этого сообщения будет создано сообщение LM_DRAWITEM.
71+
72+Затем сообщение LM_DRAWITEM перехватывается TWin32WidgetSet.CallDefaultWndHandler и обрабатывается в его внутренней функции:
73+
74+``` pascal
75+procedure DrawCheckListBoxItem(CheckListBox: TCheckListBox; Data: PDrawItemStruct);
76+```
77+
78+А вот реальный код для рисования элементов TCheckListBox.
79+
80+> **Note:** Это некрасиво, может быть, этот код следует перенести в LCL, чтобы у нас был общий код для рисования элементов на случай, если набор виджетов не сделает это сам.
81+
82+MSDN Docs о LISTBOX:
83+
84+- <http://msdn2.microsoft.com/en-us/library/bb775146(VS.85>).aspx
85+- <http://msdn2.microsoft.com/en-us/library/bb775149(VS.85>).aspx
86+
87+## FAQ
88+
89+### Обработка пользовательских сообщений в вашем окне
90+
91+Напишите мне...
92+
93+### Обработка не пользовательских сообщений в вашем окне
94+
95+Для пользовательской обработки сообщений \<= WM_USER вы должны использовать SetWindowLong из модуля Windows. Это вернет адрес текущего WndProc, так что вы можете заполучить свой WndProc следующим образом:
96+
97+``` pascal
98+begin
99+ if Msg = WM_COPYDATA then
100+ ...
101+ else CallOldWindowProc;
102+end;
103+```
104+
105+And you don't lose anything. With a clever code you can even use the same wndproc for any control, just take care to call the correct old wndproc in each case.
106+
107+И вы ничего не теряете. С умным кодом вы можете даже использовать тот же wndproc для любого элемента управления, просто позаботьтесь, чтобы вызывать правильный старый wndproc в каждом случае.
108+
109+#### Пример
110+
111+Перехватывая сообщение WM_NCHITTEST, вы можете избежать перетаскивания окна.
112+
113+> **Note:** Часть, в которой функция взаимодействует с "WM_NCHITTEST", имеет очень странный результат в Windows XP. Вы не сможете переместить окно. В Vista, с другой стороны, вы все еще можете. Комментирование этого раздела, кажется, не приносит вреда, и вы можете переместить окно программы в Windows XP.
114+
115+``` pascal
116+var
117+ PrevWndProc: WNDPROC;
118+...
119+function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT; stdcall;
120+begin
121+ if uMsg=WM_NCHITTEST then
122+ begin
123+ result:=Windows.DefWindowProc(Ahwnd, uMsg, WParam, LParam); //not sure about this one
124+ if result=windows.HTCAPTION then result:=windows.HTCLIENT;
125+ exit;
126+ end;
127+ result:=CallWindowProc(PrevWndProc,Ahwnd, uMsg, WParam, LParam);
128+end;
129+
130+//устанавливаем наш обработчик сообщений
131+procedure TForm1.FormCreate(Sender: TObject);
132+begin
133+ PrevWndProc:=Windows.WNDPROC(SetWindowLongPtr(Self.Handle,GWL_WNDPROC,PtrInt(@WndCallback)));
134+end;
135+```
136+
137+---
138+*From the Free Pascal wiki, page "Win32/64 Interface/ru", as it stood on 2019-08-07 after a change by Zoltanleo, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
139+Category: Lazarus
140+Category: Operating Systems and Platforms
141+Category: Windows
142+Category: Windows Widgetsets

Back to history