Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2 3 4

Как принять сообщения в класс без окна?


dmk ©   (29.03.17 22:17[40]

>На вашем скриншоте я вижу обычное окно с рамкой.
Ну да, только все рисуется и крутится без системных вызовов ;)
А BitBlt - ну тут извините. Windows не дает прямого доступа к видеопамяти.
Короче написал я фигню. Каюсь, грешен был. О великий TForm!!!


D7   (29.03.17 22:24[41]

Нет, вы пишете перспективную штуку, но у вас есть окно какого-то класса и очередь сообщений, не может не быть. Под виндой не может.
Поэтому нужна лёгкая прослойка между ОС/платформой и главным кодом. Для винды своя, для другого другая. А интерфейс главного не меняется.


dmk ©   (29.03.17 22:27[42]

>Поэтому нужна лёгкая прослойка между ОС/платформой и главным кодом.
Абстракция от системы есть.


Игорь Шевченко ©   (29.03.17 22:59[43]


> Дык свое.


Дык надо книжки читать, чтобы свое делать. А не плавать в базовых понятиях.


> Если намертво к windows привязаться потом тошно переделывать
> будет,
> а слово портирование забыть придется.


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

Иксы на юниксах например совсем по-другому работают, что на маке происходит - честно не знаю, но тоже не так, как на Windows. А на андроиде еще по третьему. Куда ты будешь свои WM_LBUTTONDOW переносить - я не представляю


dmk ©   (29.03.17 23:16[44]

>Игорь Шевченко ©   (29.03.17 22:59) [43]
Вы меня уничтожили :) Просто растерли.


Eraser ©   (30.03.17 07:39[45]


> Почти как FMX, но не FMX. ПРивязки к WIndows почти нет

так и в FMX привязки к windows нет.
https://ru.wikipedia.org/wiki/%D0%98%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%8F_%D0%B2%D0%B5%D0%BB%D0%BE%D1%81%D0%B8%D0%BF%D0%B5%D0%B4%D0%B0


Игорь Шевченко ©   (30.03.17 10:19[46]


> Вы меня уничтожили :) Просто растерли.


Не в этом дело. Такие задачи прекрасно решаются в рамках парадигмы Model-View-Controller, где контроллер как раз и занимается обработкой внешних событий. Таким образом решение абстрагируется от конкретных механизмов внешних событий, сосредотачивая всю конкретику в относительно небольших участках кода.
Я ведь не зря начал с того, что примеров уже уйма, посмотреть, как сделано, можно совершенно бесплатно.


dmk ©   (30.03.17 13:10[47]

Так я так и делаю. У меня отдельный класс будет, который будет заниматься вводом-выводом. Просто не успеваю все сделать. Если бы я программистом был ;) А так сижу вечерами пишу, да и то не каждый день. Много изучил, но еще больше не знаю. Учимся пока. Для меня это кажется новшеством, а у других уже есть. Ну велосипед и что? Зато свой.


An a Student   (30.03.17 20:01[48]

Просто вы, кажется, не понимаете что "окно" в Windows - это и не "форма" и не "класс". Да и вообще никакой класс не может "содержать окно", лишь побочно создавать и идентификатор хранить.
Окно - это HWND (ну или псевдоним THandle из VCL), полученное через одну из WinAPI-функций (или даже из VCL-функций/методов).
А связь своего потомка от TObject с неким HWND и с его оконной функцией - не делает ни окно "частью класса", ни наоборот.

По идее же надо передавать указатель на экземпляр объекта своего класса через lParam, нет? А вы тут что-то странное делаете - зачем так странно сабклассить собственное окно?


dmk ©   (30.03.17 23:18[49]

HWND это просто индекс или ссылка или относительный адрес структуры которой рассылается сообщение. В остальном я делаю велосипед. Не обращайте внимания.


An a Student   (31.03.17 00:31[50]

Вот именно. В классе который мы придумываем может быть только индекс/ссылка/смещение не важно что это - HWND. "Окна в классе" в принципе быть не может.

гм... Этот "class function" никогда не видел, это чего такое, типа статического метода? Думал нету в Делфи статических. И у таких не будет первого скрытого параметра "self/this"? Ну дак в случае с WndProc тогда и нету смысла так делать.

Классика - передавать указатель на объект в CreateWindowEx() в lParam и в WM_CREATE записывать его в GWL_USERDATA. Зачем извращаться-то? :)


DVM ©   (01.04.17 22:10[51]


> dmk ©

не забудь еще что без цикла выборки сообщений, работать ничего не будет.


> An a Student   (31.03.17 00:31) [50]


> Этот "class function" никогда не видел, это чего такое,
> типа статического метода? Думал нету в Делфи статических.
>  И у таких не будет первого скрытого параметра "self/this"?
>

Этого недостаточно, все равно будут скрытые параметры. Нужно еще слово  static.


dmk ©   (01.04.17 22:15[52]

>не забудь еще что без цикла выборки сообщений, работать ничего не будет.
Отдельного цикла нет. Просто трансляция из оконной процедуры. Все работает.


DVM ©   (01.04.17 22:20[53]


> dmk ©   (01.04.17 22:15) [52]


> Отдельного цикла нет.

Как это нет? У тебя же родительское окно есть. Есть. Значит и цикл есть.


DVM ©   (01.04.17 22:35[54]

По моему, тут вообще не нужно никаких окон и сообщений.
Нужно ядро, и два контроллера, ввода и вывода. Общение между ними не нуждается в сообщениях. Все общение ядра с внешним миром определяется контроллерами. Контроллер ввода прекрасно может перехватывать сообщения формы и транслировать их в ядро.


dmk ©   (01.04.17 22:57[55]

Это типа узловой связи клиент-сервер?


D7   (03.04.17 03:38[56]

так... В общем что-то я совсем заморочился, наплодил нечто объёмное и сырое. Но общую суть как-то так:

type
 MouseButton = (buttonLeft, buttonRight, buttonMiddle);

function TWindow64WndProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var Window64: TWindow64;
begin
Window64:=TWindow64(GetWindowLong(Wnd, GWL_USERDATA)); // получаем текущий объект!
case Msg of
 WM_CREATE: // сообщение приходит одним из первых и однократно для каждого создаваемого HWND
   begin
   SetWindowLong(Wnd, GWL_USERDATA, Integer(PCreateStruct(lParam).lpCreateParams)); // сохраняем текущий объект так!
   Result:=0;
   end;
 WM_PAINT:
   begin
   Window64.OnMessagePaint(Wnd, wParam);
   Result:=0;
   end;
 WM_LBUTTONDOWN:
   begin
   Window64.OnMouseDown(Smallint(lParam And $FFFF), Smallint(lParam Shr 16), buttonLeft, ... );
   Result:=0;
   end;
 WM_LBUTTONUP:
   begin
   Window64.OnMouseUp(Smallint(lParam And $FFFF), Smallint(lParam Shr 16), buttonLeft, ... );
   Result:=0;
   end;
 WM_RBUTTONDOWN:
   begin
   Window64.OnMouseDown(Smallint(lParam And $FFFF), Smallint(lParam Shr 16), buttonRight, ... );
   Result:=0;
   end;
 WM_RBUTTONUP:
   begin
   Window64.OnMouseUp(Smallint(lParam And $FFFF), Smallint(lParam Shr 16), buttonRight, ... );
   Result:=0;
   end;
 else
   Result:=DefWindowProc(Wnd, Msg, wParam, lParam); // !!!
 end;
end;

procedure TWindow64.OnMessagePaint(Wnd: HWND; wParam: WPARAM);
var DC: HDC; Rect: TRect; PS: TPaintStruct;
begin
if (wParam<>0) then
 DoPaint(HDC(wParam), nil)
else
 if GetUpdateRect(Wnd, Rect, False) then
   begin
   DC:=BeginPaint(Wnd, PS);
   DoPaint(DC, @Rect);
   EndPaint(Wnd, PS);
   end
 else
   { nothing };
end;

procedure TWindow64.DoPaint(DC: HDC; Rect: PRect);
begin
// Делаем BitBlt или StrechDIBits на DC переданный через параметры
end;

procedure TWindow64.OnMouseDown(X: Integer; Y: Integer; Button: MouseButton, ... );
begin
//
end;

procedure TWindow64.OnMouseUp(X: Integer; Y: Integer; Button: MouseButton, ... );
begin
//
end;

constructor TWindow64.Create(AParent: THandle; ABitmap: TBitmap64; R: TRegion);
var Rect: TRect;
begin
...
 FWndClassEx.lpfnWndProc := @TWindow64WndProc; // и всё, больше ничего не надо мутить!
...
 FStyle:=WS_VISIBLE Or WS_OVERLAPPEDWINDOW;
 FStyleEx:=WS_EX_APPWINDOW;
 with Rect do
   begin
   Left:=FClientLeft;
   Top:=FClientTop;
   Right:=Left+FClientWidth;
   Bottom:=Top+FClientHeight;
   AdjustWindowRectEx(Rect, FStyle, False, FStyleEx);
   FHandle:=Windows.CreateWindowEx(
                                                      FStyleEx,
                                                      LPCWSTR(FWndClassEx.lpszClassName),
                                                      'TWindow64',
                                                      FStyle,
                                                      Left,
                                                      Top,
                                                      Right-Left,
                                                      Bottom-Top,
                                                      0, // !!!
                                                      0,
                                                      HInstance,
                                                      Pointer(Self) // и передаём ссылку на текущий объект сюда!
                              );
   end;
...
end;


И не забывайте про всякие *DBLCLK. А зачем нужна какая-то самодельная "трансляция"?
В каждый объект TWindow64 нажатие будет само приходить (если курсор был над ним), даже если оно будет дочернее.

> DVM ©   (01.04.17 22:35) [54]

эм... Я тоже не особо понял, если не сложно, расскажите пожалуйста всем поподробнее об этом? Спасибо!


dmk ©   (03.04.17 05:59[57]

У меня смысл такой, что приходится обходить ограничения Windows на доступ к видеопамяти, т.к. в проекте у меня все рисуется в буфере, то и контролы нужно рисовать в буфере. Поэтому и придумал такой вариант. Зато его можно и в буфер рисовать и на DC рисовать, хотя DC и есть буфер, только у системы.

Проще покзать, чем объяснить. Тут 2 экзешника:
https://cloud.mail.ru/public/bkmv/YUqSxabFZ

TBitmap - там CheckBox в буфере рисуется, а в ic64 скроллы и линейки.
Про смысл не спрашивайте.


D7   (03.04.17 10:38[58]

Под Win7 не стартится, видимо exe-шники только под 64. А старые демки (из соседних тем) уже не доступны, жаль, я бы с радостью посмотрел.

Можно и на OpenGL всё рисовать. Видеопамять, пожалуйста. :)

Непонятно тока что за "трансляция". Если у вас много окон (группа HWND) - то им сообщения сами придут.
А если они не реальные окна - то им не надо создавать HWND и что-то слать, оперировать вручную, вызывать методы если требуется.

Вы можете убрать из кода ваши секретные разработки (рисование на ассемблере и прочее, вообще их по логике в отдельных модулях надо хранить), оставить только базовые классы типа TWindow64, часть которых привязана к Windows, и скинуть куда-то сей урезанный проект?


D7   (03.04.17 10:46[59]

Под моей Win7 имелось ввиду. Попробую найти 64, но в идеале бы было бы чтоб работало и на 32 тоже. *

Я же говорю - я очень хорошо понимаю задумку, но некоторые вещи что вы делаете (видно по кускам кода) не укладываются в подобную архитектуру.
Что-то слегка не так, я хочу помочь это исправить.


Страницы: 1 2 3 4 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо