powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / message WM_SYSCOMMAND or WM_CONTEXTMENU
25 сообщений из 27, страница 1 из 2
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808441
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно ли как то заставить 1 обработчик глотать два сообщения ?
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808446
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
зай чем? (С)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808459
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий,

На сколько я понимаю, он создаёт в классе селектор с меткой WM_*, и при вызове определённого сообщения достаёт его из своих недалёких vmt мест. Можно Думаю динамически отредактировать его, и задать к примеру на создание формы. Это стоит проверить, что бы на один и тот же обработчик ссылались разные сообщения
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808463
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
30.04.2019 17:39, shonli95 пишет:
> На сколько я понимаю, он создаёт в классе селектор с меткой WM_*

кито?! (С)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808487
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кто нибудь знает как писать в защищённую память? Считать то я могу, я вижу сколько методов с WM_* Я знаю их адреса.

Стоит только попробовать что то поменять, сразу в AV падает

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
procedure AddMethod(&Class: Pointer; Selector: SmallInt; MethodAddress: Pointer);
type
  PArrayMethod = ^TArrayMethod;
  TArrayMethod = array of SmallInt;

  TDynaMethodTable = record
    Count: Word;
    Selectors: array [0 .. 9999999] of SmallInt;
  end;

  PDynaMethodTable = ^TDynaMethodTable;
var
  Tabl: PDynaMethodTable;
  Addrs: PPointer;
  OldCount: Word;
  T: PArrayMethod;
begin
  Tabl := PPointer(PByte(PPointer(&Class^)^) + VmtDynamicTable)^;
  if Tabl <> nil then
  begin
    OldCount := Tabl.Count;
    Tabl.Count := Tabl.Count + 1;
    // inc(Tabl.Count);

    T := @Tabl.Selectors;
    SetLength(T^, Tabl.Count);

    Addrs := PPointer(PByte(T) + OldCount * SizeOf(Tabl.Selectors[0]));
    PPointer(PByte(Addrs) + OldCount * SizeOf(Pointer))^ := MethodAddress;
  end;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  AddMethod(@Self, WM_SYSCOMMAND, Self.MethodAddress('SysCommand'));
end;
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808490
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
30.04.2019 18:13, shonli95 пишет:
> Кто нибудь знает как писать в защищённую память?

а поцчему вы спrашиваите? (С)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808610
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всё получилось, динамически ставить эти обработчики

Код: pascal
1.
2.
  AddMethod(@Self, WM_SYSCOMMAND, Self.MethodAddress('SysCommand'));
  AddMethod(@Self, WM_CONTEXTMENU, Self.MethodAddress('SysCommand2'));




Весь код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.AppEvnts, Vcl.StdCtrls;

type
  TForm4 = class(TForm)
    procedure SysCommand(var Message: TMessage); // message WM_SYSCOMMAND;
    procedure SysCommand2(var Message: TMessage);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

type
  TMethodTest = procedure of object;

implementation

{$R *.dfm}

procedure AddMethod(&Class: Pointer; Selector: SmallInt; MethodAddress: Pointer);
{$POINTERMATH ON}
label NewStart, EndStep;
type
  ArrPointer = array of Pointer;

  TArrayMethod = array of SmallInt;

  TDynaMethodTable = record
    Count: Word;
    Selectors: array [0 .. 9999999] of SmallInt;
  end;

  PDynaMethodTable = ^TDynaMethodTable;
var
  Tabl: PDynaMethodTable;
  Addrs1, Addrs2, Ptr: PPointer;
  OldCount, I: Word;
  OldProtect: Cardinal;

  Addres, BytePtr: PByte;
  MNewStart: Boolean;
begin
  Addres := PByte(PPointer(&Class^)^);
NewStart: MNewStart := False;
  Ptr := PPointer(Addres + VmtDynamicTable);
  BytePtr := PByte(Ptr);
  if VirtualProtect(BytePtr, SizeOf(BytePtr^), PAGE_EXECUTE_READWRITE, OldProtect) then
  begin
    try
      Tabl := Ptr^;
      if Tabl = nil then
        goto EndStep;

      OldCount := Tabl.Count;

      Addrs2 := PPointer(PByte(@Tabl.Selectors) + Tabl.Count * SizeOf(Tabl.Selectors[0]));

      Tabl.Count := Tabl.Count + 1;

      Addrs1 := PPointer(PByte(@Tabl.Selectors) + Tabl.Count * SizeOf(Tabl.Selectors[0]));

      I := OldCount;
      while I > 0 do
      begin
        Dec(I);
        ArrPointer(Addrs1)[I] := ArrPointer(Addrs2)[I];
      end;

      ArrPointer(Addrs1)[OldCount] := MethodAddress;

      Tabl.Selectors[OldCount] := Selector;

    EndStep:

      if Tabl = nil then
      begin
        GetMem(PPointer(Addres + VmtDynamicTable)^, Sizeof(TDynaMethodTable));
        MNewStart := True;
      end;

    finally
      VirtualProtect(BytePtr, SizeOf(BytePtr^), OldProtect, OldProtect);
      FlushInstructionCache(GetCurrentProcess, BytePtr, SizeOf(BytePtr^));
    end;
    if MNewStart then
      goto NewStart;
  end;

end;

procedure TForm4.SysCommand2(var Message: TMessage);
begin
  Message.Result := 0;
end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  AddMethod(@Self, WM_SYSCOMMAND, Self.MethodAddress('SysCommand'));
  AddMethod(@Self, WM_CONTEXTMENU, Self.MethodAddress('SysCommand2'));
end;

procedure TForm4.SysCommand(var Message: TMessage);
begin
  Form4.Caption := Message.WParam.ToString;
end;

end.

...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39808651
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот для чего это делалось
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
unit FormHookEX;

interface

uses
  Winapi.Windows, Vcl.Forms, Winapi.Messages;

type
  ThookMessage = class(TForm)
    procedure CallMessage(var Message: TMessage);
  end;

 procedure FormSetHookMessage(Form: TForm);  // Могу запретить любой форме делать всё, что укажу 

procedure AddMethod(&Class: Pointer; Selector: SmallInt; MethodAddress: Pointer);

implementation

 procedure ThookMessage.CallMessage(var Message: TMessage); 
 begin 
   if Message.Msg = 123 then 
     Message.Result := 0 
   else 
     case Message.WParam of 
       61441, 61443, 61444, 61445, 61447, 61456, 61458, 61472, 61488, 61490, 61536, 61539, 61587, 
         61696, 61730: Message.Result := 0 
     else DefWindowProc(Handle, Message.Msg, Message.WParam, Message.LParam) 
     end; 
 end; 

procedure FormSetHookMessage(Form: TForm);
begin
  AddMethod(@Form, WM_SYSCOMMAND, @ThookMessage.CallMessage);
  AddMethod(@Form, WM_CONTEXTMENU, @ThookMessage.CallMessage);
end;

procedure AddMethod(&Class: Pointer; Selector: SmallInt; MethodAddress: Pointer);
label NewStart, EndStep;
type
  ArrPointer = array of Pointer;

  TArrayMethod = array of SmallInt;

  TDynaMethodTable = record
    Count: Word;
    Selectors: array [0 .. 9999999] of SmallInt;
  end;

  PDynaMethodTable = ^TDynaMethodTable;
var
  Tabl: PDynaMethodTable;
  Addrs1, Addrs2, Ptr: PPointer;
  OldCount, I: Word;
  OldProtect: Cardinal;

  Addres, BytePtr: PByte;
  MNewStart: Boolean;
begin
  Addres := PByte(PPointer(&Class^)^);
NewStart: MNewStart := False;
  Ptr := PPointer(Addres + VmtDynamicTable);
  BytePtr := PByte(Ptr);
  if VirtualProtect(BytePtr, SizeOf(BytePtr^), PAGE_EXECUTE_READWRITE, OldProtect) then
  begin
    try
      Tabl := Ptr^;
      if Tabl = nil then
        goto EndStep;

      OldCount := Tabl.Count;

      Addrs2 := PPointer(PByte(@Tabl.Selectors) + Tabl.Count * SizeOf(Tabl.Selectors[0]));

      Tabl.Count := Tabl.Count + 1;

      Addrs1 := PPointer(PByte(@Tabl.Selectors) + Tabl.Count * SizeOf(Tabl.Selectors[0]));

      I := OldCount;
      while I > 0 do
      begin
        Dec(I);
        ArrPointer(Addrs1)[I] := ArrPointer(Addrs2)[I];
      end;

      ArrPointer(Addrs1)[OldCount] := MethodAddress;

      Tabl.Selectors[OldCount] := Selector;

    EndStep:

      if Tabl = nil then
      begin
        GetMem(PPointer(Addres + VmtDynamicTable)^, Sizeof(TDynaMethodTable));
        MNewStart := True;
      end;

    finally
      VirtualProtect(BytePtr, SizeOf(BytePtr^), OldProtect, OldProtect);
      FlushInstructionCache(GetCurrentProcess, BytePtr, SizeOf(BytePtr^));
    end;
    if MNewStart then
      goto NewStart;
  end;

end;

initialization

finalization

end.

...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809012
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95Вот для чего это делалось
Но... зачем ?..
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809014
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точнее вот это .
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809224
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

Почему никто раньше не мог подсказать? Я то показался в проперти формы, и не нашел ничего такого

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
unit FormHookEX;

interface

uses
  Vcl.Forms, Vcl.Controls, Winapi.Messages;

type
  ThookMessage = class(TForm)
    procedure CallMessage(var Message: TMessage);
    function GetFormHookEXWndProc(): TWndMethod;
  end;

procedure FormSetHookMessage(Form: TForm);

procedure FormRemoveHookMessage(Form: TForm);

implementation

function ThookMessage.GetFormHookEXWndProc(): TWndMethod;
begin
  Result := WndProc;
end;

procedure ThookMessage.CallMessage(var Message: TMessage);
begin
  if Message.Msg = 123 then
    Message.Result := 0
  else
    case Message.WParam of
      61441, 61443, 61444, 61445, 61447, 61456, 61458, 61472, 61488, 61490, 61536, 61539, 61587,
        61696, 61730: Message.Result := 0
    else WndProc(Message);
    end;
end;

procedure FormSetHookMessage(Form: TForm);
var
  T: TWndMethod;
begin
  TMethod(T).Data := Form;
  TMethod(T).Code := @ThookMessage.CallMessage;
  TControl(Form).WindowProc := T;
end;

procedure FormRemoveHookMessage(Form: TForm);
var
  T, T2: TMethod;
  V: function: TWndMethod of object;
begin
  T := TMethod(TControl(Form).WindowProc);
  if T.Code = @ThookMessage.CallMessage then
  begin
    TMethod(V).Data := Form;
    TMethod(V).Code := @ThookMessage.GetFormHookEXWndProc;

    TControl(Form).WindowProc := V();
  end;
end;

initialization

finalization

end.

...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809304
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95alekcvp, Почему никто раньше не мог подсказать?

Возможно вот поэтому .
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809306
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вторую ссылку не читали, да? :)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
type
  TFormHook = class helper for TForm
    procedure CallMessage(var Message: TMessage);
    procedure HookForm;
    procedure UnhookForm;
  end;

...

procedure TFormHook.CallMessage(var Message: TMessage);
begin
  if Message.Msg = 123 then
    Message.Result := 0
  else
    case Message.WParam of
      61441, 61443, 61444, 61445, 61447, 61456, 61458, 61472, 61488, 61490, 61536, 61539, 61587,
        61696, 61730: Message.Result := 0
    else 
       WndProc(Message);
    end;
end;

procedure TFormHook.HookForm;
begin
   WindowProc := CallMessage;
end;

procedure TFormHook.UnhookForm;
begin
   WindowProc := nil;
end;

...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809307
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибся:
WindowProc := nilWndProc;
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809316
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvpshonli95alekcvp, Почему никто раньше не мог подсказать?

Возможно вот поэтому .

Нет. Это не профессионализм со стороны форума. Я вижу ответ таким -

авторНевозможно установить один message на два фронта, но это возможно сделать с помощью WindowProc,настроив коллбэк в ручную, на данные сообщения


... А не

Мимопроходящийзай чем? (С)


Мимопроходящий
кито?! (С)



Это просто лишь бы посмеяться и посмотреть, что же мозг ТС изобретёт в конечном итоге.

Конечно не нужно исключать того, что Мимопроходящий и сам не знал как это сделать
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809325
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95,

Тут прибежали санитары и зафиксировали нас. (с)
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809344
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad F,

Ой - Наркоши. Наркоши, цветные геймороши (С)
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809348
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95,
Какая у кого классика, такие и заботы/алгоритмы, очевидно.
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809363
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95Это просто лишь бы посмеяться и посмотреть, что же мозг ТС изобретёт в конечном итоге.

Справка - для слабаков, исходники - для дураков, правда? :)
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809365
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

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

А то чё, не исходников не справки нет??? Для слабаков ? Ко, ко петушкам таким, которые не могут нагуглить нужное, а в справке так просто по "windows message", "winapi message" не найдёшь
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809515
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95,

Форум нужен когда в справке чего-то нет или что-то непонятно.
А когда люди приходят спрашивать "как сделать чтобы в TLabel текст был красненьким" или "как запретить пользователю нажимать на кнопку в программе" - это смешно, да.

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

P.S: Я никогда не использовал ни метод WndProc, ни свойство WindowProc в своих программах, но узнал об их существовании из гугла за 5 минут.
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809594
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

Кээээп, мой случай : Что-то непонятно. Понятно???)))) Непонятно было как установить message в два положения на один обработчик


Ответ должен был быть что это невозможно. А не крики умирающей птицы, что этот вопрос есть

Так как я хз как это гуглилось, и в справке искалось, опять по второй случай попадает - непонятно. Понятно?
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809604
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95alekcvp,
Ответ должен был быть что это невозможно. А не крики умирающей птицы, что этот вопрос есть


Почему невозможно? Возможно, через то самое место, как ты это сам сделал :)
Но вот зачем это было нужно, если твоя задача решалась парой строк кода совсем другим методом?..
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809646
shonli95
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

=_= Такое чувства что я переписываюсь с ан....


Во первых, невозможно через конструкцию языка message.

Во вторых, это сделано было потому, что нагуглить другое решение невозможно было с моими значениями как это сделать

По этому я полез смотреть в исходники как работает message и понял как это переписать (Конечно же после поиска такого волшебного метода как WindowProc)


.... Так что.
...
Рейтинг: 0 / 0
message WM_SYSCOMMAND or WM_CONTEXTMENU
    #39809699
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
shonli95alekcvp,
Так как я хз как это гуглилось, и в справке искалось, опять по второй случай попадает - непонятно. Понятно?
( если не открывает )
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / message WM_SYSCOMMAND or WM_CONTEXTMENU
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]