IdNotify : How to pass parameteres to function - indy

I have code typhoon with lazarus installed after a long strugle I have managed to include the unit IdSync to my project.
How can I pass parameteres to a function that I want to execute in the main thread from TIdNotify ?

You have to override the TIdNotify.DoNotify() method, then you can pass whatever parameters you want, eg:
type
TMyNotify = class(TIdNotify)
protected
procedure DoNotify; override;
end;
procedure TMyNotify.DoNotify;
begin
SomeFunction(parameters);
end;
.
begin
...
TMyNotify.Create.Notify;
...
end;
Presumably, you want the calling thread to specify the parameter values, so just make them members of the class, eg:
type
TMyNotify = class(TIdNotify)
protected
Param1: SomeType;
Param2: SomeType;
Param3: SomeType;
procedure DoNotify; override;
end;
procedure TMyNotify.DoNotify;
begin
SomeFunction(Param1, Param2, Param2);
end;
.
begin
...
with TMyNotify.Create do
begin
Param1 := ...;
Param2 := ...;
Param3 := ...
Notify;
end;
...
end;

Related

push procedure pop function with sequence number in oracle

I want to write code for push with procedure and pop with Function .
create or replace package pushpop_demo as
procedure push(val varchar2);
function pop return varchar2;
end pushpop_demo;
create or replace package body pushpop_demo as
subtype my_string_subtype is varchar2(100);
type varchar2_ntt is table of my_string_subtype;
stuff varchar2_ntt := varchar2_ntt();
procedure push(val varchar2)
is
begin
stuff.extend;
stuff(stuff.last) := val;
end push;
function pop return varchar2
is
subtype my_string_subtype varchar2(100);
begin
if stuff is not empty then
val := stuff(stuff.last);
stuff.delete(stuff.last);
end if;
return val;
end pop ;
but I get error , my question is how can I do this problem with sequence number ??? or other solution .my code does not run anyway . also I do not want use the package .just with procedure and Function .please help me
You need / statement terminators to terminate each PL/SQL block.
You are missing an END; statement at the end of the package body.
You have not declared the VAL variable in the function.
You do not want to re-declare the my_string_subtype type (as it will shadow sub-type declared in the package body).
You can initialise the collection in the declaration section or an alternative is to initialise it in the BEGIN ... END section of the package body.
create or replace package pushpop_demo as
procedure push(val varchar2);
function pop return varchar2;
end pushpop_demo;
/
create or replace package body pushpop_demo as
subtype my_string_subtype is varchar2(100);
type varchar2_ntt is table of my_string_subtype;
stuff varchar2_ntt; -- := varchar2_ntt();
procedure push(val varchar2)
is
begin
stuff.extend;
stuff(stuff.last) := val;
end push;
function pop return varchar2
is
val my_string_subtype;
begin
if stuff is not empty then
val := stuff(stuff.last);
stuff.delete(stuff.last);
end if;
return val;
end pop;
BEGIN
stuff := varchar2_ntt();
END;
/
Then you can use:
BEGIN
pushpop_demo.push('World');
pushpop_demo.push('Hello');
END;
/
and then:
BEGIN
DBMS_OUTPUT.PUT_LINE(pushpop_demo.pop());
DBMS_OUTPUT.PUT_LINE(pushpop_demo.pop());
END;
/
Outputs:
Hello
World
fiddle

Why throw an exception when multiplying?

I want square ,but i dont remember how to do it becauseI multiplying is a variable, but throw exeption and i don't know why.
please help i don't know what else to do
program Project1;
uses crt;
type TSquare=class
len:integer;
place:integer;
function Perimetr:integer;
function Area:integer;
function Verify():boolean;
procedure Show(P,S:real);
constructor Create(P,l:integer);
end;
function TSquare.Perimetr:integer;
var P:integer;
begin
P:=len*4;
end;
function TSquare.Area:integer;
var S:integer;
begin
S:=len*len;
end;
function TSquare.Verify:boolean;
begin
end;
procedure TSquare.Show(P,S:real);
begin
write('Площидь=',S,'Перимитр=',P);
end;
constructor TSquare.Create(p,l:integer);
begin
len:=l;
place:=p;
end;
var r: TSquare;
a,b:integer;
begin
r.Create(1,5);
r.Show(r.Perimetr(),r.Area());
end.
SIGSEGV means access of invalid memory. Here you do not create the TSquare object correctly.
r := TSquare.Create(1,5); is the correct way to create an instance of an object.

Procedure checking set up parameters (PL/SQL, ORACLE)

In the package I have couple of procedure that set global variables, example below:
...
PROCEDURE setA (pp IN VARCHAR2)
IS BEGIN global_vName := pp; END;
PROCEDURE setB (qq IN VARCHAR2)
IS BEGIN global_vColor := qq; END;
FUNCTION getA RETURN VARCHAR2
IS BEGIN RETURN global_vName; END;
FUNCTION getB RETURN VARCHAR2
IS BEGIN RETURN global_vColor; END;
...
Now in the PL/SQL block I'm doing test if they are working correclty:
Begin
mypack.setA('NameA');
mypack.setB('ColorB');
End;
How to write a procedure that will check if global_vName and global_vColor are set up?
If they are null procedure should return exception. Please help.
Do you mean this?
FUNCTION getA RETURN VARCHAR2 IS
BEGIN
IF global_vName IS NULL THEN
RAISE NO_DATA_FOUND;
END IF;
RETURN global_vName;
END;
There is no possibility to execute some code after the end statement - you should write it explicitly if you need additional check. As I understand, you want be sure that global variables are always initialized, so you can use the package initialization:
create or replace package body mypack as
PROCEDURE setA (pp IN VARCHAR2)
IS BEGIN global_vName := pp; END;
PROCEDURE setB (qq IN VARCHAR2)
IS BEGIN global_vColor := qq; END;
FUNCTION getA RETURN VARCHAR2
IS BEGIN RETURN global_vName; END;
FUNCTION getB RETURN VARCHAR2
IS BEGIN RETURN global_vColor; END;
< here are your other functions and procedures >
begin
-- here is an initialization section
setA('NameA');
setB('ColorB');
end mypack;
The initialization section will be executed automatically by Oracle before the first user's call to package (function, procedure, cursor, variable, etc.). So you can be sure that your variables are always initialized.

Referencing Service.Name crashes after moving service code to ancestor

I had a unit for a Windows (32 bit) service that was built up like this:
unit uSvcBase;
interface
type
TMyServiceBase = class(TService)
procedure ServiceBeforeUninstall(Sender: TService);
procedure ServiceCreate(Sender: TObject);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure ServiceExecute(Sender: TService);
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceAfterInstall(Sender: TService);
private
public
function GetServiceController: TServiceController; override;
end;
var
MyServiceBase: TMyServiceBase;
implementation
{$R *.DFM}
{$R SvcEventLogMessages.res}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
MyServiceBase.Controller(CtrlCode);
end;
function TMyServiceBase.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
const
rsServiceMessages =
'SYSTEM\CurrentControlSet\Services\EventLog\Application';
procedure TMyServiceBase.ServiceAfterInstall(Sender: TService);
var
lReg : TRegistry;
lAppName: String;
begin
lReg := TRegistry.create;
try
with lReg do
begin
Rootkey := HKEY_LOCAL_MACHINE;
if OpenKey(rsServiceMessages, False) then
begin
if OpenKey(MyServiceBase.Name, True) then
begin
lAppName := ParamStr(0);
WriteString('EventMessageFile', lAppName);
WriteString('CategoryMessageFile', lAppName);
WriteInteger('CategoryCount', 2);
WriteInteger('TypesSupported', EVENTLOG_ERROR_TYPE OR EVENTLOG_WARNING_TYPE OR EVENTLOG_INFORMATION_TYPE);
CloseKey;
end;
CloseKey;
end; { if OpenKey }
end; { with lReg }
finally
lReg.Free;
end;
end;
Because I needed to make a second service which was largely identical, I decided to make this a 'base' unit that others derive from (you can already see that in the names above):
unit uSvcTasks;
interface
uses
System.SysUtils, System.Classes, uSvcBase;
type
TMyServiceScheduler = class(TMyServiceBase)
procedure ServiceCreate(Sender: TObject);
private
public
end;
var
MyServiceScheduler: TMyServiceScheduler;
implementation
{%CLASSGROUP 'System.Classes.TPersistent'}
{$R *.dfm}
Uses uTypesAlgemeen;
procedure TMyServiceScheduler.ServiceCreate(Sender: TObject);
begin
inherited;
// Set some properties
end;
At design time, the MyServiceScheduler.Name in this descendant differs from the MyServiceBase.Name.
Issue: The AfterInstall now crashed. Trying to use the original code using OpenKey(MyServiceBase.Name was not allowed.
I worked around his by using a property for the name (setting it in the descendant Create), but I do not understand why referencing MyServiceBase.Name in the AfterInstall does not work. Can anyone explain?
Thanks to Uwe Raabe's comments I was able to figure out how to fix this:
The project had an Application.CreateForm(TMyServiceScheduler, MyServiceScheduler) in the project source which initializes MyServiceScheduler, but there was nothing initializing MyServiceBase, so refering to it was illegal.
Replace the reference to MyServiceBase.Name with Name in the AfterInstall(That should've been done anyway).
Move the code for the ServiceController from uSvcBase to uSvcTasks

Passing arguments to write within a procedure

How can I pass arguments from my procedure to a call of write called inside ?
Something quite like that:
procedure smth (args: alltypes);
begin
write(args);
end;
If you want to use your function with any number/type of argument in Write manner, like smth(3, 'aaa', 5.6) - it is impossible as i know. However you can use array of ... type for argument to pass to the procedure any number of arguments.
Here is an example:
program wrt;
{$mode objfpc}{$H+}
uses
sysutils, variants;
procedure test1(args: array of Variant);
var
i: Integer;
begin
for i := Low(args) to High(args) do
Write(args[i]);
Writeln;
end;
procedure test2(fmt: string; args: array of const);
begin
Writeln(Format(fmt, args));
end;
begin
test1([1, 'aaa', 3.5, False]);
test2('%d %s %g, %s', [1, 'aaa', 3.5, BoolToStr(False, True)]);
end.
For example:
procedure write( text : string );
begin
write( text );
end;
But if you want to override your function. You have to read that topic HERE. That will allow you to make function with more type of arguments.

Resources