Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];

Вниз

Обработка событий в приложении без формы.   Найти похожие ветки 

 
independant   (2004-02-19 11:23) [0]

Подобная тема уже затрагивалась->
http://delphimaster.net/view/1-1076510033/
особо обратил внимание на [16] [17], но ничего не получилось:(
Могли бы привести кусок работающего кода для приложения без формы: необходимо обрабатывать сообщения от таймера, т.е. как создать процедуру Timer1.Timer, а в процедуре к примеру showmessage("...").
Спасибо.


 
clickmaker   (2004-02-19 11:34) [1]

см. SetTimer, TimerProc в MSDN


 
Юрий Зотов   (2004-02-19 11:39) [2]

> как создать процедуру Timer1.Timer

Прямо в программе создать потомок TTimer и пусть сам же обрабатывает свое же событие.

type
TMyTimer = class(TTimer);
public
constructor Create(AOwner: TComponent); override;
procedure Tick(Sender: TObject);
end;

constructor TMyTimer.Create(AOwner: TComponent);
begin
inherited;
OnTimer := Tick
end;

procedure TMyTimer.Tick(Sender: TObject);
begin
...
end;

Соответственно, в программе без Application Вам придется реализовать собственный механизм выборки и обработки сообщений.


 
Anatoly Podgoretsky   (2004-02-19 11:44) [3]

Вообще то спрашиваешь не про события, а про сообщения, а события не привязаны к окнам и будут работать.
В примере от ЮЗ это OnTimer := Tick


 
independant   (2004-02-19 14:03) [4]

Вопрос, конечно, ламерский, но как создать приложение без формы?При старте Delphi по умолчанию выбирается New-Application, где есть форма, а Project->Remove from Project->вопрос-удалить сам модуль Unit1.pas-далее закрываются все окна-а при выборе Project->View Source появляется окно модуля, где в Uses присутствует Forms, после begin Application.Initialize и Application.Run, но ведь мне как раз этого и не надо!
Спасибо.


 
Плохиш   (2004-02-19 14:09) [5]

>independant (19.02.04 14:03) [4]

На клавиатуре есть кнопки "del" и "backspace".


 
Юрий Зотов   (2004-02-19 14:11) [6]

> где в Uses присутствует Forms, после begin
> Application.Initialize и Application.Run,
> но ведь мне как раз этого и не надо!

А кто мешает убрать все ненужное руками? Минимальная работающая Delphi-программа состоит только из begin и end.


 
independant   (2004-02-19 18:21) [7]

2 Юрий Зотов-а Вы уверены что в строке
TMyTimer = class(TTimer) ;
необходима запятая?
При непоставленной запятой при компиляции выдается единственная ошибка-в строке
constructor Create(AOwner: TComponent); override;
Undeclared identifier:TComponent
и соответственно

var
timer1:TMyTimer;

begin
timer1:=TMyTimer.Create(); в этой строке
timer1.Interval:=1000;
end.
Not enought actual parameters.

При поставленой запятой сообще около 10 ошибок:(


 
Юрий Зотов   (2004-02-19 18:36) [8]

> independant (19.02.04 18:21) [7]

Конечно, точку с запятой надо убрать. Неужели не понятно, что это обыкновенная описка?

И конечно в uses надо добавить Сlasses. Неужели даже самая элементарная азбука тоже требует пояснений? Как же Вы тогда собираетесь написать вот это:

"Соответственно, в программе без Application Вам придется реализовать собственный механизм выборки и обработки сообщений".


 
independant   (2004-02-19 18:59) [9]

Вот именно-как его реализовать???
Следующий код "вешает" Delphi практически сразу...

program Project1;

uses
SysUtils,
Windows,
Classes,
Dialogs,
StdCtrls, ExtCtrls,QStdCtrls,QExtCtrls,
ScktComp;

type TMyTimer=class(TTimer)
public
constructor Create(AOwner:TComponent);override;
procedure Tick(sender:TObject);
end;

constructor TMyTimer.Create(AOwner: TComponent);
begin
inherited;
OnTimer:=Tick;
end;

procedure TMyTimer.Tick(Sender: TObject);
begin
showmessage("on Tick");
end;

{$R *.res}
var
timer1:TMyTimer;
begin
timer1:=TMyTimer.Create(nil);
timer1.Enabled:=true;
timer1.Interval:=1000;

end.
Может подскажете статью, а то я никак не пойму:(


 
independant   (2004-02-22 15:47) [10]

Все же я буду очень признателен, если мне подскажут как в программе без Application реализовать собственный механизм выборки и обработки сообщений.
Спасибо.


 
jack128   (2004-02-22 16:44) [11]


> independant (22.02.04 15:47) [10]
м-дя..Короче давай ТЗ, договоримся об оплате и я те напишу и цикл выборки сообщений и много замечательных вещей ;-))

P.S. RTFM


 
independant   (2004-02-23 15:08) [12]

Вот уж не ожидал :)
Просмотрел через поиск очень много инфы о RTFM, но связаного с Delphi что-то нет :(
Буду очень благодарен, если подкинете ссылку на хорошую статью или хотя-бы небольшой франмнт кода, по которому можно аналогичное написать. Но в "напишу и цикл выборки сообщений" речь идет о перехвате сообщений Windows API-функциями? Т.е. надо ставить hook? Или что-то вроде GetMessage?

В общем help,plz.


 
Юрий Зотов   (2004-02-24 17:49) [13]

> independant (23.02.04 15:08) [12]

Стандартный цикл выборки сообщений выглядит так:

var
Msg: TMsg;

while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg)
end;

Он работает, пока не поступит сообщение WM_QUIT. Обычно для его поылки в очередь используют PostThreadMessage.


 
Defunct   (2004-02-24 18:02) [14]

А можно поинтересоваться зачем Вы хотите создать приложение без форм?

1. Хотите содать приложение минимального объема?
2. Просто хотите чтобы не было видно главной формы приложения?

Если второе, то есть такой ответ:
Добавьте в DPR файл строку:

Application.ShowMainFowm := False;
Application.Run


PS :Подготовил этот ответ еще вчера, но вот были какие-то проблемы с сервером, с смог вчера запостить...


 
Romkin   (2004-02-24 18:13) [15]

Почему все уперлись именно в обработку сообщений без формы? что стоит сделать невидимое простое окно на API и делать через него? Если SetTimer хотит HWND, таки дайте ему HWND :)


 
Юрий Зотов   (2004-02-24 18:45) [16]

> Romkin (24.02.04 18:13) [15]

Именно так и работает TTimer. Именно поэтому и нужен цикл выборки сообщений.


 
Игорь Шевченко   (2004-02-24 18:53) [17]

Судя по системе, вполне может подойти CreateWaitableTimer, он без окошек и не требует цикла выборки...


 
Romkin   (2004-02-24 19:03) [18]

Я думаю, может просто

function CallbackWndProc(Window: HWND; Message: Cardinal;
wParam, lParam: Longint): Longint; stdcall;
begin
if Message = WM_TIMER then //упс!
//таймер приехал
else
Result := DefWindowProc(Window, Message, wParam, lParam);
end;

var
CallbackWindowClass: TWndClass = (
style: 0;
lpfnWndProc: @CallbackWndProc;
cbClsExtra: 0;
cbWndExtra: 0;
hInstance: 0;
hIcon: 0;
hCursor: 0;
hbrBackground: 0;
lpszMenuName: nil;
lpszClassName: "TCallbackWindow");

procedure RegisterCallbackWindowClass;
var
TempClass: TWndClass;
ClassRegistered: Boolean;
begin
CallbackWindowClass.hInstance := HInstance;
ClassRegistered := GetClassInfo(HInstance, CallbackWindowClass.lpszClassName,
TempClass);
if not ClassRegistered or (TempClass.lpfnWndProc <> @CallbackWndProc) then
begin
if ClassRegistered then
Windows.UnregisterClass(CallbackWindowClass.lpszClassName, HInstance);
Windows.RegisterClass(CallbackWindowClass);
end;
end;

initialization
RegisterCallbackWindowClass;


остается
FCallbackWnd :=
CreateWindow(CallbackWindowClass.lpszClassName, PChar("TIMER_BACKCALL"), 0,
0, 0, 0, 0, 0, 0, HInstance, nil);
Окно вроде есть... Его в таймер и совать :)))


 
Romkin   (2004-02-24 19:09) [19]

Упс. Тожесамо TTimer делает :) Что-то я под вечер того


 
independant   (2004-02-26 11:56) [20]

2 defunct [14]-mne nuzno prilozenije minimalnogo objema, a predlagaemom Vami v punkte 2 sposobe ja znaju, spasibo.

2 Jurij Zotov-kazdij tip soobsenija msg:TMsg imejet msg.message,t.e. unikalnij nomer. Gde mozno dostat polnij spisok soobsenij Windows i ih nomera? Ja vospolzovalsia vasim sovetom, ispolzuju GetMessage, no voznikli trudnosti-vot fragment koda:

program Project1;
{$APPTYPE CONSOLE}

uses
SysUtils,
Classes,
Windows,
ScktComp,
Registry,
ShellAPI;

type TMyServerSocket=class(TServerSocket)
public
constructor Create(AOwner:TComponent);override;
procedure MyClientRead(sender:TObject;
Socket: TCustomWinSocket);

private
name2:string;
size:integer;
receive:Boolean;
mem_str2:TMemoryStream;
public
{ Public declarations }
end;

constructor TMyServerSocket.Create(AOwner:TComponent);
begin
inherited;
onClientRead:=MyClientRead;
end;

procedure showtext(t:string);
begin
MessageBox(0,pchar(t),"message",MB_OK);
end;

procedure TMyServerSocket.MyClientRead(sender:TObject;
Socket: TCustomWinSocket);
begin
showtext("socket received -> "+socket.ReceiveText);
end;

//programa
var
serv:TMyServerSocket;
msg:TMsg;
begin
serv:=TMyServerSocket.Create(nil);
serv.Port:=3001;
serv.Open;
while GetMessage(msg,0,0,0) do
begin
if msg.message=1025 then serv.MyClientRead(nil,nil);
end;
serv.Close;
showtext("end");
end.

Kak ja opredelil eksperimentalno :), pri posilke klientom teksta voznikajet soobsenije s nomerom 1025.Klientskaja proga-obicnoje okonnoje prilozenije.Zapuskaju server, zatem klient.Klient obrabativaet onConnect(i jafiksiruju cto soedinenije ustanovlenno), a zatem pri posilke teksta v servere voznikaet:

Exception EAccessViolation in module server at...
Access violation at adress...posle cego soedinenije "is forsibly closed" i razumeetsia v kliente voznikaet Asynchronous Socket error 10053.Podozrevaju cto problema v videlennoj stroke.
Budu priznatelen esli objasniat kak obrabatyvat soobsenija ot soketov v konsolnih prilozenijah.

Sorry za translit.


 
Digitman   (2004-02-26 12:15) [21]


> independant (26.02.04 11:56) [20]


все это замечательно, хоть и коряво

ты вот о другом задумайся прежде всего - каким образом твой юзер сможет интерактивно взаимодействовать (например, дать некую команду с клавиатуры, по которой приложение должно завершиться) с твоим конс.приложением, если в нем крутится "бесконечный" цикл while GetMessage() do и нигде не вызывается ни одна из ф-ций ожидания ввода с клавиатуры !

наиболее корректное и очевидное решение - организация доп.код.потока, который будет работать с TServerSocket, в то время как осн.код.поток будет занять конс.вводом/выводом и управлением доп.потоком


 
independant   (2004-02-26 13:33) [22]

2 Digitman-дело в том, что //{$APPTYPE CONSOLE}-окна не будет и эта программа не предусматривает интерактивного взаимодействия.
Програма работает все время, как комп загружен и время от времени получает от клиента сообщения, на которые сервер и должен реагировать(выполнять какие либо действия или отсылать клиенту строки-SendText(...).
Меня больше заботит то, почему происходит ошибка(см [20]).
Хотя буду признателен если приведете код с реализацией доп.кодового потока.
> все это замечательно, хоть и коряво

В чем? Выслушиваю критику :)


 
BlackTiger   (2004-02-26 14:19) [23]

2independant: Уважаемый! Какое консольное приложение? Вы чё, с дерева упали? То, что описано в предыдущем посте - сервис!

Может вам еще описать как РЕЗИДЕНТНАЯ программа в Delphi6 пишется? Для Win2k/XP ! :))) С добрым утром! 21-й век на дворе! А они еще поDOSовски думают, мрак.


 
independant   (2004-02-26 14:33) [24]

2 BlackTiger-ignored
У кого есть предложения насчет [22]?


 
WebErr   (2004-02-26 15:43) [25]

Есть такая штука в Windows API, как

UINT SetTimer(

HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);

Здесь просто укажи: (1) Handle формы, потом (2) идентификатор таймера (просто какое-то число), потом (3) количество миллисекунд - частота таймера, а потом просто nil, потому как в противном случае тебе придёться возиться с процеДурой таймера. Дальше: ловишь WM_TIMER, проверяешь

wTimerID = wParam

И если это твой таймер, то всё Ok! Делай что твоей душе угодно! Кстати это можно сделать запросто и в 16-битной программе и в 32-битной - разницы не будет. В общем удачи, монстр WinAPI! :))))


 
WebErr   (2004-02-26 15:45) [26]

Не забудь убить бедолагу таймера!

BOOL KillTimer(

HWND hWnd, // handle of window that installed timer
UINT uIDEvent // timer identifier
);


 
independant   (2004-02-26 15:53) [27]

2 WebErr-да что вы все к таймеру пристали.Это я про таймер спрашивал к примеру, чтобы понять механизм обработки событий в приложении без формы.Я же в последних постах ясно про сокеты спрашиваю !
P.S.Хотя про таймер еще вопросы будут :)


 
Digitman   (2004-02-26 16:00) [28]


> дело в том, что //{$APPTYPE CONSOLE}-окна не будет и эта
> программа не предусматривает интерактивного взаимодействия.


мил ты мой, а на кой ляд тебе тогда консоль-то !?
консоль таки подразумевает интерактивное взаимодействие !

тебе в таком случае сервис-процесс нужен. а не консоль)


 
independant   (2004-02-26 16:12) [29]

2 Digitman-я вообще полагал, что (если не брать во внимание KOL) консоль-минимальный размер(меньше уж никак).Однако если сервис занимает меньше, то просьба помочь.Как [20] переделать?


 
Digitman   (2004-02-26 16:18) [30]


> консоль-минимальный размер


и что тебе дался этот "размер" ? на машинах под NT дисковое пр-во, распределенное под файл размером +-500 кб, - тьфу !!)) ... что 4 кб, что 400 мб ... никакой разницы)

но зато сервис как раз и предназначен для фоновой (во многих случаях - неинтерактивной) работы процесса


 
Digitman   (2004-02-26 16:23) [31]


> Как [20] переделать?


выкинь из головы свои "заморочки с размерами"

создай приложение-сервис (File - New - Service Application ..)
брось на модуль данных компонент TServerSocket

дальше ,практически, все как в обычном GUI-приложении
и никаких забот с очередью сообщений - все уже Борланд сделал за тебя)


 
independant   (2004-02-26 16:28) [32]


> выкинь из головы свои "заморочки с размерами"

Никак нет, размер критичен.
> и что тебе дался этот "размер" ? на машинах под NT дисковое
> пр-во, распределенное под файл размером +-500 кб, - тьфу
> !!)) ... что 4 кб, что 400 мб ... никакой разницы)

Не мог бы мысль пояснить, что-то я не совсем...
Все же очень прошу помочь с [20]! Как (остановимся на консоли) избежать ошибки? Ведь должно передаваться нормально:(


 
Digitman   (2004-02-26 16:47) [33]


> independant (26.02.04 16:28) [32]



> Никак нет, размер критичен.


с твоего позволения я останусь при сувоем мнении - блажь это, и не более того


> Как (остановимся на консоли) избежать ошибки? Ведь должно
> передаваться нормально


serv.OnClientRead := Serv.MyClientRead;
...

while GetMessage(msg,0,0,0) do
Dispatchmessage(msg);


 
Digitman   (2004-02-26 16:52) [34]

в догонку к [31] скажу, что если ты таки используешь VCL для транспорта посредством TServerSocket, то "консоль или не консоль" - это такое "тьфу" !!)) .. по сравнению с принципиальным использованием или неиспользованием VCL)


 
Юрий Зотов   (2004-02-26 18:05) [35]

> WebErr © (26.02.04 15:43) [25]
> Здесь просто укажи: (1) Handle формы

КАКОЙ формы, когда ни одной формы нет?

Сказка про белого бычка. Вы предыдущие сообщения читали?



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.008 c
1-25808
LAMER-XP
2004-02-25 23:26
2004.03.09
Всех с праздником! м вопросик заодно


1-25816
Galerus
2004-02-25 20:39
2004.03.09
TStringGrid


3-25695
garry79
2004-02-07 12:18
2004.03.09
Как после вызова ХП обратиться к набору данных?


1-25806
sohat
2004-02-27 09:12
2004.03.09
Memo с выделением зарезервированных слов для скриптов


1-25741
Goida
2004-02-26 17:10
2004.03.09
Точное время!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский