Сейчас на форуме: tyns777, JustLife, zds, 2nd, morgot, Rio, CDK123, tihiy_grom (+4 невидимых)

 eXeL@B —› Программирование —› Перетаскивать окно за любую точку.
. 1 . 2 . >>
Посл.ответ Сообщение


Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 06 февраля 2009 22:04 · Поправил: Mavlyudov
· Личное сообщение · #1

Если делать для стандартного приложения в делфи, то перетаскивание будет выглядеть вот так:

public
procedure ttt(var M:TMessage); message WM_NCHITTEST;
end;
.......................................
procedure TForm1.ttt(var M:TMessage);
begin
inherited;
if M.Result = htClient then M.Result := htCaption;
end;

Но у меня консольное приложение, в котором я решил создать форму:

form: TForm;
form := TForm.Create(Application);
.........
Как тут сделать перетаскивание???
нужно ведь как-то динамически привязать message к форме...

Что-то типа
ReleaseCapture;
form.perform(WM_SysCommand, $F012, 0);

не помогает..




Ранг: 138.1 (ветеран)
Активность: 0.090
Статус: Участник
Одепт ЭкзэЛаба

Создано: 06 февраля 2009 22:19
· Личное сообщение · #2

Я делаю так:

Code:
  1. WM_LBUTTONDOWN:
  2.   begin
  3.     ReleaseCapture;
  4.     SendMessage(hWin, WM_NCLBUTTONDOWN, HTCAPTION, 0);
  5.   end;




Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 06 февраля 2009 22:19
· Личное сообщение · #3

Mavlyudov
form.onmousedown?

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74





Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 06 февраля 2009 22:35 · Поправил: Mavlyudov
· Личное сообщение · #4

g-l-u-k
Что-то я не вижу, куда обработчик вставить...

Code:
  1. var
  2. form: TForm;
  3. FormThread: THandle;
  4. procedure FormWork;
  5. var x:integer;
  6. begin
  7.   form := TForm.Create(Application);
  8.   form.BorderStyle:=bsNone;
  9.   form.Visible:=true;
  10.   form.Width:=500;
  11.   form.Height:=300;
  12. end;
  13. procedure CreateFrm;
  14.   var
  15.    ThreadID:dword;
  16.   begin
  17.    FormThread := CreateThread(nil,0,@FormWork,nil,0,ThreadID);
  18.   end;
  19. begin
  20. CreateFrm;
  21. readln;
  22. end.





Ранг: 138.1 (ветеран)
Активность: 0.090
Статус: Участник
Одепт ЭкзэЛаба

Создано: 06 февраля 2009 22:51
· Личное сообщение · #5

Mavlyudov пишет:
g-l-u-k
Что-то я не вижу, куда обработчик вставить...

Забыл сказать что этот кодес я использую в связке delphi + winapi чтобы перетаскивать форму за любую область.




Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 06 февраля 2009 22:52 · Поправил: Mavlyudov
· Личное сообщение · #6

g-l-u-k
это и так понятно..А как мне в мой код внедрить?
Может можно как-то через функцию Dispatch(M) ?



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 07 февраля 2009 02:23
· Личное сообщение · #7

Mavlyudov
Вот, проверенно, 100% работат.

procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
Perform (WM_SYSCOMMAND,SC_MOVE+2,0);
end;




Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 07 февраля 2009 02:43 · Поправил: Mavlyudov
· Личное сообщение · #8

F_a_u_s_t
Ну ты молодец конечно.
Где ты такие процедуры возьмешь?
У меня не стандартное приложение делфи!
Весь код я привел выше и туда не получится вставить то, что ты написал!



Ранг: 65.7 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 07 февраля 2009 03:11 · Поправил: Halt
· Личное сообщение · #9

Mavlyudov
слушай если ты форму создаешь все равно руками дык сделай ее на WinAPi, чем прикручивать сюда оконную продцедуру.. которая к томуже раздует твое приложение на +400 кб минимум

с другой стороны:
вот как выгдялит создание формы на WinAPi
Code:
  1.   with WinClass do
  2.   begin
  3.    Style := CS_PARENTDC; //ñòèëü êëàññà ãëàâíîãî îêíà
  4.    hIcon := LoadIcon(hInst,'MAINICON'); //èêîíêà ïðîãðàììû
  5.    lpfnWndProc := @WindowProc; //íàçíà÷åíèå îáðàáîò÷èêà ñîîáùåíèé
  6.    hInstance := hInst;
  7.    hbrBackground := COLOR_BTNFACE + 1; //öâåò îêíà
  8.    lpszClassName := 'Editor Class'; //êëàññ îêíà
  9.    hCursor := LoadCursor(0, IDC_ARROW); //àêòèâíûé êóðñîð
  10.   end;
  11. Handle := CreateWindowEx(0, 'Editor Class', 'LineAge 2 C4 Dat Editor v1.2.4',
  12. WS_OVERLAPPEDWINDOW or
  13. WS_VISIBLE,
  14. 244, 127, 696, 473,
  15. 0, 0,
  16. hInst, nil);

@WindowProc продцедура обработки сообщений
WinClass:TWinClass


Code:
  1. function WindowProc(hwnd, msg, wparam, lparam: longint): longint; stdcall; //îáðàáîò÷èê ñîîáùåíèé
  2. begin
  3.   Result := DefWindowProc(hwnd, msg, wparam, lparam);
  4.    case Msg of
  5.    WM_LBUTTONDOWN:
  6.      begin
  7.         ReleaseCapture;
  8.         SendMessage(hWin, WM_NCLBUTTONDOWN, HTCAPTION, 0);
  9.      end;
  10.   end;


вариант №2 (я считаю он через ж.. ибо тащишь все...)

Code:
  1. program Project1;
  2. {$APPTYPE CONSOLE}
  3. uses
  4.   SysUtils, windows, system,classes, forms, messages;
  5. type
  6.   TForm1 = class(TForm)
  7.   private
  8.     { Private declarations }
  9. public
  10. procedure ttt(var M:TMessage); message WM_NCHITTEST;
  11. end;
  12. procedure TForm1.ttt(var M:TMessage);
  13. begin
  14. inherited;
  15. if M.Result = htClient then M.Result := htCaption;
  16. end;
  17. begin
  18.   { TODO -oUser -cConsole Main : Insert code here }
  19. end.

работает или нет ХЗ но компилится...




Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 07 февраля 2009 18:31
· Личное сообщение · #10

Halt
ошибка "Resource TForm1 not found" пишет
А {$R *.DFM} нельзя вставить, у меня же консоль



Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 07 февраля 2009 21:36
· Личное сообщение · #11

Люди если форма создается из экземпляра TForm значит OnMouseDown у нее уже есть. Просто его надо динамически присвоить.

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74




Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 08 февраля 2009 00:17 · Поправил: F_a_u_s_t
· Личное сообщение · #12

Mavlyudov
Я прекрасно понял о чем ты писал.
Stack пишет : Люди если форма создается из экземпляра TForm значит OnMouseDown у нее уже есть. Просто его надо динамически присвоить.
Конечно динамически присваивать надо если форма динамически создается.
Ну или сразу создать форму а в ней создать консоль.
Mavlyudov
Кто тебе сказал что нельзя написать дерективу {$R *.dfm}?
Тебя обманули.



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 08 февраля 2009 00:25
· Личное сообщение · #13

Mavlyudov
Вот тебе для примера.
Code:
  1. unit Unit4;
  2. interface
  3. uses
  4. Windows, Messages, Classes, Controls, Forms;
  5. type
  6. TForm4 = class(TForm)
  7. procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  8.   end;
  9. var
  10.   Form4: TForm4;
  11. implementation
  12. {$*.dfm}
  13. procedure TForm4.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  14. begin
  15.   ReleaseCapture;
  16.   Perform (WM_SYSCOMMAND,SC_MOVE+2,0);
  17. end;
  18. {$APPTYPE CONSOLE}
  19. begin
  20.   write('FormMouseDown');
  21. end.





Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 08 февраля 2009 01:22
· Личное сообщение · #14

F_a_u_s_t пишет:
Кто тебе сказал что нельзя написать дерективу {$R *.dfm}?
Тебя обманули.

Нельзя просто потому что компилятор будет искать файл project.dfm.
А такого файла нет!!!



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 08 февраля 2009 01:40
· Личное сообщение · #15

Mavlyudov
А кто сделать тебе не дает?
Или тебе обязательно динамически надо?
Еще как вариант все это в либу перенисти и подключить к основной проге - консоли.
Если динамически то и конструкторы,методы и процедуры тоже динамически надо обьявлять.
Кстати в королевстве делфи была такая тема на форуме там давали несколько примеров для совмещения консоли и формы... если не потерли то там и лежит.



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 08 февраля 2009 02:04
· Личное сообщение · #16

Вот откомпиленный вариан с {$R *.dfm} :


Halt 1 вариан тоже работает - проверял 2 не знаю не пробовал.
А по нормальному имхо все таки это надо в либу выносить.

99b5_07.02.2009_CRACKLAB.rU.tgz - Project2.rar



Ранг: 63.8 (постоянный), 2thx
Активность: 0.030
Статус: Участник

Создано: 08 февраля 2009 12:04
· Личное сообщение · #17

Mavlyudov

читаем MSDN -> SetWindowLong / GWL_WNDPROC



Ранг: 4.3 (гость)
Активность: 0=0
Статус: Участник

Создано: 08 февраля 2009 23:01
· Личное сообщение · #18

Mavlyudov
[quote]ошибка "Resource TForm1 not found" пишет[/quote]
Создавай форму через
Form1 := TForm1.Create( nil, 1 ); // Ключевой момент - второй параметр

Тогда не будет ресурс формы искать.



Ранг: 65.7 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 08 февраля 2009 23:07
· Личное сообщение · #19

drin пишет:
читаем MSDN -> SetWindowLong / GWL_WNDPROC


ха ха ха.. а ларчик просто ) зачет не знал, я извращением таким не занимался никогда
спасибо



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 08 февраля 2009 23:19 · Поправил: Clerk
· Личное сообщение · #20

Halt
Это не извращение, а нормальный системный механизм; извращение это типа "TForm1.ttt(var M:TMessage)".
Get~/SetWindowLong() позволяют получить/переопределить оконную процедуру, но только в контексте текущего процесса. Тоесть мы получаем указатель на оригинальный хэндлер, задаём свой. Далее мы обрабатываем как и скозал уже g-l-u-k сообщение WM_LBUTTONDOWN, посылая WM_NCLBUTTONDOWN(HTCAPTION), после чего передаём управление на оригинальный диспетчер.



Ранг: 65.7 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 08 февраля 2009 23:29
· Личное сообщение · #21

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



Ранг: 17.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 09 февраля 2009 00:31
· Личное сообщение · #22

Вот) в примере:
0. Создание окна в консольном приложении (точнее, TForm)
1. Создание кнопки и обработка её нажатия
2. перетаскивание окна за любое (даже не пристойное =) ) место


79e1_08.02.2009_CRACKLAB.rU.tgz - Project1.rar




Ранг: 156.2 (ветеран), 2thx
Активность: 0.090
Статус: Участник

Создано: 09 февраля 2009 10:43 · Поправил: Mavlyudov
· Личное сообщение · #23

ne0 пишет:
Form1 := TForm1.Create( nil, 1 ); // Ключевой момент - второй параметр


Это для какой версии делфи? у меня пишет: Too mane actual parametrs

zombiee
Работает даже без этой строчки:
DragMouse:=TMyEventHandler.Create;



Ранг: 17.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 09 февраля 2009 11:25
· Личное сообщение · #24

to Mavlyudov:
Я знаю, это подстраховка от ошибок )



Ранг: 65.7 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 09 февраля 2009 15:49 · Поправил: Halt
· Личное сообщение · #25

немного поэкспериментировал над проектом zombiee , получилось вот так, тоже самое но форма создается нормально, через Dfm а потом просто копируется со всеми файлами (pas, res, dfm) в папку к консольному проекту, единственное но - по закрытие консоли вылазит violation но мне думает это из-за кривой работы делфей с памятью, это у нее наследственное.. можно просто отловить... а может как подправить...


да и потом открывается в делфях уже с формы...



Ранг: 65.7 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 09 февраля 2009 15:52
· Личное сообщение · #26

97a9_09.02.2009_CRACKLAB.rU.tgz - 111.zip



Ранг: 17.7 (новичок)
Активность: 0.020
Статус: Участник

Создано: 09 февраля 2009 21:45 · Поправил: zombiee
· Личное сообщение · #27

to Halt:
Во-во, я тоже самое получал) попробуй ЯВНО задать form.Close; или form.Free;
Извиняюсь, явно вызвать при Application.OnTerminate;



Ранг: 63.8 (постоянный), 2thx
Активность: 0.030
Статус: Участник

Создано: 10 февраля 2009 01:47
· Личное сообщение · #28

Halt пишет:
ха ха ха.. а ларчик просто ) зачет не знал, я извращением таким не занимался никогда
спасибо

просто лично я не вижу смысла загонять себя в рамки VCL или других классов/объектов когда есть штатные API для таких вещей, например вдруг автор завтра решит что ему VCL не подходит и заюзает KOL или вообще начнет юзать виндовый API для GUI и ему придется все переделывать, а так с SetWindowLong оно в любом исполнении будет работоспособным решением



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 10 февраля 2009 02:02
· Личное сообщение · #29

drin
Я вобще не вижу смысла писать консоль и при этом юзать классы.
Вчем выгода консоли если юзать классы?
Размеры будут ого го лучше сразу GUI делать.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 10 февраля 2009 04:13 · Поправил: Clerk
· Личное сообщение · #30

Halt
Перечитывал тут, чуть пацтол не упал
> оконную продцедуру.. которая к томуже раздует твое приложение на +400 кб минимум
У тебя какието баги в конпиляторе, это просто не возможно.. У меня оконная процедура заняла 39 байт с учётом пересчёта дельтасмещания, без него и того меньше:
Code:
  1. comment '
  2. LONG
  3. NtUserSetWindowLong(
  4.     IN HWND hwnd,
  5.     IN int nIndex,
  6.     IN LONG dwNewLong,
  7.     IN BOOL bAnsi);'
  8.     
  9. RedirectionAndDispatchWindowProc proc WindowHandle:HANDLE
  10.          push TRUE
  11.          Call dt01
  12. dt01:
  13.          add dword ptr [esp],(offset NewEntry - offset dt01)  ;WindowProc
  14.          push GWL_WNDPROC
  15.          push WindowHandle
  16.          mov eax,1220h       ;NtUserSetWindowLong
  17.          mov edx,esp
  18.          int 2eh
  19.          lea esp,[esp + 4*4]       ;Remove frame.
  20.          Call dt02
  21. dt02:
  22.          pop edx
  23.          mov dword ptr [edx + (offset OldEntry - offset dt02)],eax         ;WindowProc
  24.          ret
  25. ;
  26. NewEntry:
  27.          Call dt03
  28. dt03:
  29.          cmp dword ptr [esp + 3*4],WM_LBUTTONDOWN    ;uMsg
  30.          pop edx
  31.          jne @f
  32.          mov dword ptr [esp + 2*4],WM_NCLBUTTONDOWN  ;uMsg ->
  33.          mov dword ptr [esp + 3*4],HTCAPTION         ;wParam
  34. @@:
  35.          jmp dword ptr [edx + (offset OldEntry - offset dt03)]
  36. OldEntry:
  37.          PVOID ?
  38. RedirectionAndDispatchWindowProc endp

Я взял сервис фиксированной константой(XPSP2), код должен быть в секции доступной для записи, но это я тестил. Реально в вам это не нужно; я исходил из того, что оконная процедура является рекурсией, например SendMessage() сводится к вызову тойже оконной процедуры, посылая только иные коды, чем были приняты до вызова.
Проще говоря, чтоб не юзать никакие апи необходимо просто текущие коды изменить, тоесть:
Code:
  1. uMsg -> WM_NCLBUTTONDOWN
  2. wParam -> HTCAPTION

Более ничего не нужно делоть.


. 1 . 2 . >>
 eXeL@B —› Программирование —› Перетаскивать окно за любую точку.
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати