Вверх ↑
Этот топик читают: Гость
Ответов: 817
Рейтинг: 52
#1: 2018-01-15 15:00:16 ЛС | профиль | цитата
Добрый день!
Читаю разные умные книги и прочел, что есть разные методы обработки окон
умная книга писал(а):

Как было сказано выше имеются два способа, а на самом деле два режима, обработки событий GUI: режим MessageLoop и режим OnEvent. Оба режима - это просто два различных способа обработки событий GUI. Выбранный режим зависит от личных предпочтений и некоторых особенностей в назначении создаваемого GUI. Оба режима абсолютно равноправны, но иногда один из режимов более предпочтителен по сравнению с другим.

Объясните мне пожалуйста чем один режим предпочтительнее другого (когда что использовать) и какой используется в HiAsm при создании программ?
карма: 1

0
Ответов: 1926
Рейтинг: 172
#2: 2018-01-15 15:27:56 ЛС | профиль | цитата
Ну, для начала можно поискать в интернете: http://seomg.ru/autoit/rezhim-messageloop-autoit.php

КМК, MessageLoop работает на более низком уровне, принимая все оконные сообщения (типа кликанья мыши, нажатия клавиш и пр.), а OnEvent - это стандартные события (которые построены на обработке всё тех же сообщений системы), т.е. грубо говоря более удобные оболочки. Вот пример из mianform:
function THIMainForm._onMessage;
var
sControl: PControl;
i: integer;
// acc: boolean;
begin
Result := false;
if (Msg.message = WM_INNERMESSAGE) and not isMain and
(_prop_FormFastening <> nil){ and isWindowVisible(Control.Handle)} then
begin
sControl := _prop_FormFastening.ctrlpoint;
MoveWindow(Control.Handle, sControl.Left + _prop_ShiftLeft, sControl.Top + _prop_ShiftTop,
Control.Width, Control.Height, true);
end
else
case Msg.message of
WM_ERASEBKGND:
if not Bitmap.Empty then begin
Result := true;
Rslt := 1;
end;
WM_ACTIVATE:
if Msg.WParam > 0 then _hi_OnEvent(_event_onActivate)
else if Msg.WParam = 0 then _hi_OnEvent(_event_onDeActivate);
WM_CLOSE: Result := _onClose(Control,(Msg.lParam=0));
WM_SIZE:
begin
if isMain and Assigned(Applet) then Applet.Width := Control.Width;
if _prop_Name <> '' then
for i := 0 to FormList.Count - 1 do
PostMessage(FormList.Objects[i], WM_INNERMESSAGE, 0, 0);
end;
WM_MOVE:
begin
if isMain and Assigned(Applet) then
Applet.SetPosition(Control.Left,Control.Top);
// if _prop_Name <> '' then
for i := 0 to FormList.Count - 1 do
PostMessage(FormList.Objects[i], WM_INNERMESSAGE, 0, 0);
_hi_OnEvent(_event_onMove);
end;
end;
Result := Result or inherited _onMessage(Msg,Rslt);
end;

Тут, например, отлавливаем WM_CLOSE. А вместо этого можно было написать:
Applet.OnClose := onCloseApp;
OnClose - это уже событие (но вызывается также сообщением системы, просто от глаз программиста это скрыто).

В HiAsm используется и так и так. Просто не на все сообщения есть события, иногда приходится (или удобнее) использовать сообщения.

Вроде так.

Редактировалось 1 раз(а), последний 2018-01-15 15:28:46
карма: 9
0
Ответов: 817
Рейтинг: 52
#3: 2018-01-15 16:45:15 ЛС | профиль | цитата
3042, Ничего не понял из примера mianform:, но в остальном вроде улавливаю мысль
Спасибо.
карма: 1

0
Ответов: 5227
Рейтинг: 587
#4: 2018-01-15 17:02:16 ЛС | профиль | цитата
-= DriveR =-, Как универсальное средство для улавливания мысли , остальные WM_Message ищи в MSDN

Add(MainForm,1839434,371,175)
{
Width=520
Height=355
Caption="Hook IC demo"
Point(Handle)
}
Add(InlineCode,2108213,371,238)
{
WorkPoints=#11:doStartHook|10:doStopHook|
EventPoints=#7:onEvent|
DataPoints=#4:hwnd|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|59:uses Windows, Kol, Share, Debug, Messages{, CallbackThunk};|0:|4:type|33: TCallbackThunk = class(TObject)|9: private|26: FCallAddress: Pointer;|22: FProcPtr: Pointer;|25: FSavedFlag: LongWord;|22: FSelfPtr: Pointer;|37: function GetCallAddress: Pointer;|8: public|46: constructor Create(pSelf, pProc: Pointer);|33: destructor Destroy; override;|20: procedure Clear;|54: property CallAddress: Pointer read GetCallAddress;|8: end; |2: |4:type|29: THiAsmClass = class(TDebug)|9: private|27: FThunk: TCallbackThunk;|8: public|34: hwnd, onEvent: THI_Event; |16: Child: Hwnd;|25: NewAddress: Pointer; |24: OldAddress: LongInt;|23: constructor Create;|55: procedure doStartHook(var _Data:TData; Index:word);|54: procedure doStopHook(var _Data:TData; Index:word);|59: function ChildCallback(HWnd: THandle; Msg: Cardinal; |64: WParam, LParam: Integer): Cardinal; Stdcall; |6: end;|2: |0:|14:implementation|0:|67:function THiAsmClass.ChildCallback(HWnd: THandle; Msg: Cardinal; |61: WParam, LParam: Integer): Cardinal; Stdcall; |8:begin |15: case Msg of |59: WM_LBUTTONDOWN: _hi_onEvent(onEvent,'onMouse_LDown');|59: WM_RBUTTONDOWN: _hi_onEvent(onEvent,'onMouse_RDown');|58: WM_LBUTTONUP: _hi_onEvent(onEvent,'onMouse_LUp'); |60: WM_RBUTTONUP: _hi_onEvent(onEvent,'onMouse_RUp'); |71: WM_LBUTTONDBLCLK: _hi_onEvent(onEvent,'onDblClick'); |72: WM_MOUSEMOVE: _hi_onEvent(onEvent,'onMouseMove'); |73: WM_MOUSEWHEEL: _hi_onEvent(onEvent,'onMouseWheel'); |6: |53: WM_KEYUP: _hi_onEvent(onEvent,'onKeyUp');|55: WM_KEYDOWN: _hi_onEvent(onEvent,'onKeyDown');|53: WM_PAINT: _hi_onEvent(onEvent,'onPaint');|54: WM_SIZE: _hi_onEvent(onEvent,'onResize');|56: WM_SETFOCUS: _hi_onEvent(onEvent,'onSetFocus');|57: WM_KILLFOCUS: _hi_onEvent(onEvent,'onKillFocus');|106: WM_SHOWWINDOW: _hi_onEvent(onEvent,'onShowWINDOW'); |6: end;|7: |73: Result := CallWindowProc(Pointer(GetWindowLong(HWnd, GWL_USERDATA)), |65: Hwnd, Msg, WParam, LParam); |5:end; |11: |31:constructor THiAsmClass.Create;|5:begin|32: Child := 0; NewAddress := nil;|52: // создаём переходник на THiAsmClass.ChildCallback|68: FThunk := TCallbackThunk.Create(Self, @THiAsmClass.ChildCallback);|4:end;|0:|34:procedure THiAsmClass.doStartHook;|5:begin|26: if Child <> 0 then Exit;|32: Child := 0; NewAddress := nil;|35: Child := ReadInteger(_Data,hwnd);|50: OldAddress := GetWindowLong(Child, GWL_WNDPROC);|79: // получаем адрес на процедуру или функцию сласса с произвольными параметрами|35: NewAddress := FThunk.CallAddress;|32: if NewAddress = nil then Exit;|20: // ставим ловушку |39: SetWindowLong(Child, GWL_USERDATA, |63: SetWindowLong(Child, GWL_WNDPROC, LongInt(NewAddress))); |4:end;|0:|33:procedure THiAsmClass.doStopHook;|5:begin|25: if Child = 0 then Exit;|42: // вернём родную калбэк функцию на место|39: SetWindowLong(Child, GWL_USERDATA, |51: SetWindowLong(Child, GWL_WNDPROC, OldAddress));|24: // почистим за собой |15: FThunk.Clear;|32: Child := 0; NewAddress := nil;|4:end;|0:|80://------------------------------------------------------------------------------|69:// сам переходник вынес сюда из CallbackThunk.pas (работает и в FPC)|4:type|19: PThunk = ^TThunk;|24: TThunk = packed record|17: POPEDX: Byte;|17: MOVEAX: Byte;|21: SelfPtr: Pointer;|18: PUSHEAX: Byte;|18: PUSHEDX: Byte;|14: JMP: Byte;|23: JmpOffset: Integer;|6: end;|0:|57:constructor TCallbackThunk.Create(pSelf, pProc: Pointer);|5:begin|22: FCallAddress := nil;|20: FSelfPtr := pSelf;|20: FProcPtr := pProc;|4:end;|0:|34:destructor TCallbackThunk.Destroy;|5:begin|8: Clear;|20: inherited Destroy;|4:end;|0:|31:procedure TCallbackThunk.Clear;|3:var|18: SaveFlag: DWORD;|5:begin|36: if @FCallAddress <> nil then begin|57: VirtualProtect(PThunk(@FCallAddress), SizeOf(TThunk),|29: FSavedFlag, @SaveFlag);|46: VirtualFree(FCallAddress, 0, MEM_RELEASE);|24: FCallAddress := nil;|20: FSavedFlag := 0;|6: end;|4:end;|0:|48:function TCallbackThunk.GetCallAddress: Pointer;|5:begin|34: if FCallAddress = nil then begin|82: FCallAddress := VirtualAlloc(nil, SizeOf(TThunk), MEM_COMMIT, PAGE_READWRITE);|39: with PThunk(FCallAddress)^ do begin|20: POPEDX := $5A;|20: MOVEAX := $B8;|26: SelfPtr := FSelfPtr;|21: PUSHEAX := $50;|21: PUSHEDX := $52;|17: JMP := $E9;|57: JmpOffset := Integer(FProcPtr) - Integer(@JMP) - 5;|8: end;|74: if not VirtualProtect(FCallAddress, SizeOf(TThunk), PAGE_EXECUTE_READ,|30: @FSavedFlag) then begin|26: FCallAddress := nil;|8: end;|6: end;|25: Result := FCallAddress;|4:end;|0:|4:end.|2: |
link(onEvent,338180:doEvent,[])
link(hwnd,1839434:Handle,[])
}
Add(Button,3878981,280,238)
{
Left=15
Top=25
Width=105
Caption="StartHook"
link(onClick,2108213:doStartHook,[])
}
Add(Debug,338180,476,238)
{
}
Add(Button,7773153,280,280)
{
Left=15
Top=60
Width=105
Caption="StopHook"
link(onClick,2108213:doStopHook,[(339,286)(339,251)])
}

карма: 4
Мой форум - http://hiasm.bbtalk.me/ схемы, компоненты...
0
4
Сообщение
...
Прикрепленные файлы
(файлы не залиты)