Обробка подій у додатку без форми

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

див. SetTimer, TimerProc в MSDN

> як створити процедуру Timer1.Timer

Прямо в програмі створити нащадок TTimer і нехай сам же обробляє свою подію.

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

конструктор TMyTimer.Create(AOwner: TComponent); begin inherited; OnTimer := Tick end;

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

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

Взагалі, то питаєш не про події, а про повідомлення, а події не прив'язані до вікон і працюватимуть. У прикладі від ПЗ це OnTimer := Tick

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

>independant (19.02.04 14:03) [4]

На клавіатурі є кнопки "del" та "backspace".

> де в Uses є Forms, після begin >Application.Initialize та Application.Run, > але ж мені цього й не треба!

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

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

begin timer1:=TMyTimer.Create();у цьому рядкуtimer1.Interval:=1000; end. Нет ніяких поточних параметрів.

При поставленій комі разом близько 10 помилок: (

> independant (19.02.04 18:21) [7]

Звісно, ​​крапку з комою треба прибрати. Невже не відомо, що це звичайна описка?

І звичайно в uses треба додати Сlasses. Невже навіть найпростіша абетка теж вимагає пояснень? Як же Ви тоді збираєтесь написати ось це:

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

Ось саме як його реалізувати. Наступний код "вішує" Delphi практично відразу.

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;

конструктор TMyTimer.Create(AOwner: TComponent); begin inherited; OnTimer:=Tick; end;

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

var timer1:TMyTimer; begin timer1:=TMyTimer.Create(nil); timer1.Enabled:=true; timer1.Interval:=1000;

end. Може підкажете статтю, бо я ніяк не зрозумію:(

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

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

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

> independant (23.02.04 15:08) [12]

Стандартний цикл вибірки повідомлень виглядає так:

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

Він працює, доки не надійде повідомлення WM_QUIT. Зазвичай для його напування в чергу використовують PostThreadMessage.

А можна поцікавитися навіщо Ви хочете створити програму без форм?

1. Хочете скласти додаток мінімального обсягу? 2. Просто хочете, щоб не було видно головної форми програми?

Якщо друге, то є така відповідь: Додайте в DPR файл рядок:

Application.ShowMainFowm := False;Application.Run

PS:Підготував цю відповідь ще вчора, але ось були якісь проблеми з сервером, зміг вчора запостити.

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

> Romkin (24.02.04 18:13) [15]

Саме так і працює TTimer. Саме тому й потрібний цикл вибірки повідомлень.

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

Я думаю, може просто функція 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");

процедура RegisterCallbackWindowClass; var TempClass: TWndClass; ClassRegistered: Boolean; begin CallbackWindowClass.hInstance := HInstance; ClassRegistered := GetClassInfo(HInstance, CallbackWindowClass.lpszClassName, TempClass); якщо ClassRegistered or (TempClass.lpfnWndProc <> @CallbackWndProc) then begin if ClassRegistered then Windows.UnregisterClass(CallbackWindowClass.lpszClassName, HInstance); Windows.RegisterClass(CallbackWindowClass); end; end;

залишається FCallbackWnd := CreateWindow(CallbackWindowClass.lpszClassName, PChar("TIMER_BACKCALL"), 0, 0, 0, 0, 0, 0, 0, HInstance, nil); Вікно начебто є. Його в таймер і пхати :)))

Упс. Теж саме TTimer робить :) Щось я надвечір того

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номер. Где можно достать полный список сообщений Windows и их номеров? Я використовував вашу раду, використовуючи GetMessage, не виникли труднощі-вот фрагмент коду:

використовує 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; розмір: ціле; receive:Boolean; mem_str2:TMemoryStream; публічний < Публічні заяви > end;

конструктор TMyServerSocket.Create(AOwner:TComponent); початок успадкований; onClientRead:=MyClientRead; кінець;

процедура showtext(t:рядок); begin MessageBox(0,pchar(t),"message",MB_OK); кінець;

procedure TMyServerSocket.MyClientRead(sender:TObject; Socket: TCustomWinSocket); begin showtext("сокет отримано -> "+socket.ReceiveText); кінець;

//програма var serv:TMyServerSocket; повідомлення:TMsg; begin serv:=TMyServerSocket.Create(nil); serv.Port:=3001; serv.Open; while GetMessage(msg,0,0,0) do beginif msg.message=1025 then serv.MyClientRead(nil,nil);end; serv.Close; showtext("кінець"); кінець.

Как я визначив експериментально :), при посилці клієнта тексту виникає повідомлення з номером 1025. Клієнтська прога-обічне завершення прикладення. Запускаю сервер, потім клієнт. Клієнт обробляє onConnect(і яфіксує це об'єднання встановлено), а потім при посилці тексту в сервері виникає:

Виняток EAccessViolation на сервері модуля на. Порушення доступу за адресою. після цього об'єднання "примусово закрито" і розуміється, що в клієнті виникає помилка асинхронного сокета 10053. ПідозрююЦе питання у виділеній строці. Буду приznatelen esli objasniat як obrabatyvat soobsenija ot soketov v konsolnih prilozenijah.

все це чудово, хоч і кострубато

найбільш коректне і очевидне рішення - організація дод.

2 Digitman-справа в тому, що //-вікна не буде і ця програма не передбачає інтерактивної взаємодії. Програма працює весь час, як комп завантажений і іноді отримує від клієнта повідомлення, на які сервер і повинен реагувати(виконувати якісь дії або відсилати клієнту рядки-SendText(. ). Мене більше турбує те, чому відбувається помилка(см [20]). Хоча буду вдячний якщо приведете код з реалізацією додаткового кодового потоку.> чим? Вислуховую критику :)

2independant: Шановний! Який консольний додаток? Ви що, з дерева впали? Те, що описано в попередньому пості – сервіс!

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

2 BlackTiger-ignored У кого є пропозиції щодо [22]?

Є така штука в 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!:))))

Не забудь убити бідолаху таймера! BOOL KillTimer(

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

2 WebErr-так що ви всі до таймера пристали.Це я про таймер запитував приміром, щоб зрозуміти механізм обробки подій у додатку без форми. P.S.Хоч про таймер ще питання будуть :)

> річ у тому, що //-вікна нічого очікувати і це > Програма не передбачає інтерактивної взаємодії.

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

тобі в такому разі сервіс-процес потрібен. а не консоль)

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

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

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

викинь із голови свої "заморочки з розмірами"

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

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

> викинь із голови свої "заморочки з розмірами"Ніяко ні, розмір критичний.> і що тобі дався цей "розмір"? на машинах під NT дискове > пр-во, розподілене під файл розміром +-500 кб - тьху > !!)). що 4 кб, що 400 мб. ніякої різниці)Не міг би думка пояснити, щось я не зовсім. Все ждужепрошу допомогти з [20]! Як (зупинимося на консолі) уникнути помилки? Адже має передаватися нормально: (

> Ні, розмір критичний.

з твого дозволу я залишуся при думці - дурощі це, і не більше того

> Як (зупинимося на консолі) уникнути помилки? Адже має > передаватися нормально

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

в догін до [31] скажу, що якщо ти таки використовуєш VCL для транспорту за допомогою TServerSocket, то "консоль або не консоль" - це таке "тьху"!!)) .. порівняно з принциповим використанням або невикористанням VCL)

Якої форми, коли жодної форми немає?

Казка про білого бичка. Ви читали попередні повідомлення?